Ist ein vollständig qualifizierter Klassenname bis zum globalen Geltungsbereich jemals für Definitionen von Out-of-Line-Mitgliedsfunktionen erforderlich?

14

Bei dieser Frage habe ich mich gefragt, ob es jemals nützlich / notwendig ist, Klassennamen (einschließlich des globalen Bereichsoperators) in einer nicht funktionsfähigen Elementfunktionsdefinition vollständig zu qualifizieren.

Einerseits habe ich das noch nie zuvor gesehen (und die Syntax dafür scheint dunkel zu sein). Auf der anderen Seite ist die Suche nach C ++ - Namen nicht trivial, sodass möglicherweise ein Eckfall vorliegt.

Frage:

Gibt es jemals einen Fall, in dem die Einführung einer nicht funktionierenden Elementfunktionsdefinition von von
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
abweicht
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... }(kein globales Gültigkeitsbereichspräfix ::)?

Beachten Sie, dass Definitionen von Elementfunktionen in einen Namespace eingefügt werden müssen, der die Klasse einschließt. Dies ist also kein gültiges Beispiel.

Max Langhof
quelle
Sehr neugierig, was der Downvoter an dieser Frage nicht mag. Feedback willkommen!
Max Langhof
Wann wird die Definition in einen anderen Namespace als die Deklaration gestellt? Das war es, was ich für die Frage im Sinn hatte, die Sie verlinken
idclev 463035818
oops, habe den Kleingedruckten nicht gelesen;)
idclev 463035818
@ ehemalsknownas_463035818 Das hatte ich auch im Sinn, dann habe ich es versucht und festgestellt, dass es nicht funktionieren würde, also habe ich die Frage geschrieben (andere würden sich auch fragen).
Max Langhof

Antworten:

12

Eine using-Direktive kann dazu führen Fully, dass sie ohne Einschränkung nicht eindeutig ist.

namespace Foo {
    struct X {
    };
}

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

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

Es ist notwendig, wenn man Masochist ist und gerne solche Sachen schreibt

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

   struct bar {
       void baz();
   };

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

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

Man kann natürlich die zweite Überladung wie foo::foo::bar::bazim globalen Bereich schreiben , aber die Frage war, ob die beiden Deklarationen eine unterschiedliche Bedeutung haben können oder nicht. Ich würde nicht empfehlen, solchen Code zu schreiben.

Geschichtenerzähler - Unslander Monica
quelle
Ja, dies ist in der Tat eine gültige Antwort und benötigt nicht einmal eine using. Schön, dass verschiedene Fälle hervorgehoben werden!
Max Langhof
2

Wenn eine using-Direktive verwendet wird, kann es zu einem verwirrenden Code kommen.

Betrachten Sie das folgende Demonstrationsprogramm

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

Also zur Lesbarkeit dieser qualifizierte Name

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

zeigt genau, wo die Funktion deklariert ist.

Vlad aus Moskau
quelle