c++ name-lookup global-scope qualified-name scope-resolution-operator

c++ - ¿Se requiere un nombre de clase completo hasta el alcance global para las definiciones de funciones de miembros fuera de línea?



name-lookup global-scope (3)

This pregunta me hizo preguntarme si alguna vez es útil / necesario calificar completamente los nombres de clase (incluido el operador de alcance global) en una definición de función de miembro fuera de clase.

Por un lado, nunca había visto esto antes (y la sintaxis para hacerlo correctamente parece oscura). Por otro lado, la búsqueda de nombres en C ++ no es muy trivial, por lo que tal vez exista un caso de esquina.

Pregunta:

¿Hay algún caso en el que introducir una definición de función miembro fuera de clase por
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
diferiría de
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... } (sin alcance global :: prefijo)?

Tenga en cuenta que las definiciones de funciones miembro deben colocarse en un espacio de nombres que encierra la clase, por lo que this no es un ejemplo válido.


Es necesario si uno es masoquista y le gusta escribir cosas como esta

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

Por supuesto, se puede escribir la segunda sobrecarga como foo::foo::bar::baz en alcance global, pero la pregunta era si las dos declaraciones pueden tener un significado diferente. No recomendaría escribir ese código.


Si se usa una directiva using, puede haber un código confuso.

Considere el siguiente programa demostrativo

#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; }

Entonces, para facilitar la lectura, este nombre calificado

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

muestra con precisión dónde se declara la función.


Una directiva de uso puede hacer que Fully sea ​​ambiguo sin calificación.

namespace Foo { struct X { }; } using namespace Foo; struct X { void c(); }; void X::c() { } // ambiguous void ::X::c() { } // OK