2016-05-11 3 views
0

私はBjarne StroustrupのThe C++ Programming Languageのネームスペースの章を読んで、引数依存の参照を使って関数がどのように呼び出されるのか混乱しました。クロノは、関数fの引数に使用される名前空間ですので、それはフォーマットのために成功裏に検索されるので、このコードは、私には理にかなってC++で名前空間と引数依存ルックアップについて混乱しました

スニペット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 
} 

:次は本からのコードスニペットです(日付)機能を使用します。 1(

スニペット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 
    } 
}; 

これはライン「Hまで、私には意味を構成する:また、関数fと名前空間クロノは、次のスニペットについての私を混乱させる同じスコープを、共有して表示されます); "構造体と名前空間Nの両方が同じスコープを共有しているので、なぜ "void h(int)"という関数が名前空間Nに見つからないのですか?

Stroustrupは、「引数が名前空間のメンバである場合、関連付けられた名前空間は囲む名前空間です」と言い続けています。 gへの引数は名前空間Nのメンバであるため、これは囲み名前空間が関数 "h(int)"を含まないグローバル名前空間であることを意味しますか?その場合、「フォーマット(日付)」関数も含まれていないグローバル名前空間が囲んでいる名前空間である場合、スニペット1は失敗しないのはなぜですか?

この問題についての洞察を事前にお寄せいただきありがとうございます。

+1

ここで重要なのは、ADLからのAです。** A ** rgument。 1は '名前空間N 'にない型int型です。 – Jarod42

+1

""引数が名前空間のメンバである場合 "は呼び出される関数の引数を指します –

答えて

2

ADLを呼び出し自体の引数の型に基づいて適用される関数のパラメータのないタイプのコールは、またはであってもなくてもよい。

format(d)

において、formatChronoでルックアップされるためその呼び出しの引数、dは、タイプがChrono::Dateであり、Chronoは、そのタイプの関連する名前空間です。呼び出しを含む関数がvoid f(Chrono::Date d, int i)void f()かどうかは関係ありません。 (明らかに、後者の場合、Chrono::Date d;があると仮定して)

+0

JarodとMMのおかげで、これについて混乱していると少しばかげていますが、引数 "int"自体が名前空間Nのメンバではないので、名前空間Nには見つからないだろう。最後の段落で引用したものの次の文は、 "引数が組み込み型の場合関連する名前空間はありません」これは、私が元々引用したものではなく、上記の2番目のケースに適用されていることを実現したはずのケースでした。 – hashahid

関連する問題