É necessário um nome de classe totalmente qualificado para o escopo global para definições de função de membro fora de linha?

14

Essa pergunta me fez pensar se é útil / necessário qualificar totalmente os nomes de classe (incluindo o operador de escopo global) em uma definição de função de membro fora da classe.

Por um lado, nunca vi isso antes (e a sintaxe para fazê-lo corretamente parece obscura). Por outro lado, a pesquisa de nome C ++ é muito trivial, portanto, talvez exista uma caixa de canto.

Questão:

Existe algum caso em que a introdução de uma definição de função de membro fora da classe
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
seja diferente
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... }(sem ::prefixo de escopo global )?

Observe que as definições de função de membro devem ser colocadas em um espaço para nome que encerra a classe, portanto este não é um exemplo válido.

Max Langhof
fonte
Muito curioso sobre o que o downvoter não gosta nessa questão. Feedback bem-vindo!
precisa
quando a definição é colocada em um espaço para nome diferente da declaração? Isso é o que eu tinha em mente para o quesiton que você vincula
idclev 463035818 18/11/19
oops, não leu o letras pequenas;)
idclev 463035818
@ formerlyknownas_463035818 Isso também era o que eu tinha em mente, então tentei e percebi que não iria funcionar, então escrevi a pergunta (imaginando que os outros também se perguntariam).
precisa

Respostas:

12

Uma diretiva de uso pode fazer Fullycom que seja ambígua sem qualificação.

namespace Foo {
    struct X {
    };
}

using namespace Foo;
struct X {
    void c();
};

void X::c() { } // ambiguous
void ::X::c() { } // OK
TC
fonte
5

É necessário se alguém é masoquista e gosta de escrever coisas assim

namespace foo {
    namespace foo {
        struct bar {
            void baz();
        };
    }

   struct bar {
       void baz();
   };

   void foo::bar::baz() {
   }

   void (::foo::bar::baz)() {
   }
} 

É claro que se pode escrever a segunda sobrecarga como foo::foo::bar::bazno escopo global, mas a questão era se as duas declarações podem ou não ter um significado diferente. Eu não recomendaria escrever esse código.

Contador de Histórias - Monica Sem Calúnia
fonte
Sim, essa é realmente uma resposta válida e nem precisa de a using. É bom destacar diferentes casos!
precisa
2

Se uma diretiva using for usada, pode haver um código confuso.

Considere o seguinte programa demonstrativo

#include <iostream>
#include <string>

namespace N1
{
    struct A
    {
        void f() const;
    };      
}

using namespace N1;

void A::f() const { std::cout << "N1::f()\n"; }

struct A
{
    void f() const;
};

void ::A::f() const { std::cout << "::f()\n"; }

int main() 
{
    N1::A().f();
    ::A().f();

    return 0;
}

Portanto, para facilitar a leitura, esse nome qualificado

void ::A::f() const { std::cout << "::f()\n"; }

mostra exatamente onde a função é declarada.

Vlad de Moscou
fonte