2016-05-11 6 views
0

Ich habe durch das Namespace-Kapitel in der C++ - Programmiersprache von Bjarne Stroustrup gelesen und war verwirrt darüber, wie Funktionen aufgerufen werden mit Argument-abhängige Lookup. Der folgende sind Code-Schnipsel aus dem Buch:Verwirrt über Namespaces und Argument-abhängige Lookup in C++

Snippet 1

namespace Chrono { 
    class Date { /* ... */ }; 

    bool operator==(const Date&, const std::string&); 

    std::string format(const Date&); // make string representation 
    // ... 
} 

void f(Chrono::Date d, int i) 
{ 
    std::string s = format(d); // Chrono::format() 
    std::string t = format(i); // error: no format() in scope 
} 

Dieser Ausschnitt macht Sinn für mich, da Chrono ein Namespace in der Funktion f Argumenten verwendet wird, und daher ist es erfolgreich für ein Format gesucht (Datum) Funktion. Es scheint auch die Funktion f und Namespace Chrono den gleichen Umfang zu teilen, die mir über den nächsten Schnipsel verwirrt:

Snippet 2

namespace N { 
    struct S { int i }; 
    void f(S); 
    void g(S); 
    void h(int); 
} 

struct Base { 
    void f(N::S); 
}; 

struct D : Base { 
    void mf(); 
    void g(N::S x) 
    { 
     f(x); // call Base::f() 
     mf(x); // call D::mf() 
     h(1); // error: no h(int) available 
    } 
}; 

Das macht Sinn für mich, bis die Zeile „h (1) Da beide Strukturen und Namespaces N denselben Geltungsbereich haben, warum kann die Funktion "void h (int)" nicht im Namespace N gefunden werden?

Stroustrup fährt fort zu sagen, dass "Wenn ein Argument ein Mitglied eines Namespaces ist, sind die zugeordneten Namespaces die umschließenden Namespaces." Da das Argument zu g ein Member von Namespace N ist, bedeutet dies, dass der umschließende Namespace der globale Namespace ist, der keine Funktion "h (int)" enthält? Wenn das der Fall ist, warum würde Snippet 1 nicht fehlschlagen, wenn der umschließende Namespace der globale Namespace ist, der auch keine Funktion "Format (Date)" enthält?

Vielen Dank im Voraus für einen Einblick in diese Angelegenheit!

+1

gibt es die A von ADL, die hier wichtig ist: ** A ** rgument. 1 hat den Typ "int", der nicht im Namensraum N steht. – Jarod42

+1

"" Wenn ein Argument ein Mitglied eines Namespaces ist "bezieht sich auf die Argumente der Funktion –

Antwort

2

ADL gilt, basierend auf den Typen der Argumente im Aufruf selbst, nicht die Typen der Parameter der Funktion kann der Anruf oder nicht in sein.

In format(d), format nachgeschlagen in Chrono weil Ein Argument für diesen Aufruf, d, ist vom Typ Chrono::Date, und Chrono ist ein zugehöriger Namespace dieses Typs. Ob die Funktion, die den Aufruf enthält, void f(Chrono::Date d, int i) oder void f() ist, ist irrelevant. (Offensichtlich ist im letzteren Fall, vorausgesetzt, dass es eine Chrono::Date d;.)

+0

Vielen Dank, Jarod und MM Ich fühle mich ein wenig albern wegen dieser Verwirrung, aber ich sehe jetzt, dass h würde nicht in Namespace N gefunden werden, weil sein Argument "int" selbst kein Member von Namespace N ist. Der nächste Satz im Buch nach dem, den ich in meinem letzten Absatz zitiert habe, war "Wenn ein Argument ein eingebauter Typ ist Es gibt keine damit verbundenen Namespaces. "Dies war der Fall, den ich hätte realisieren sollen, wenn ich auf den obigen zweiten Fall und nicht auf den ursprünglich zitierten ziehe. – hashahid