2017-08-01 7 views
3

http://en.cppreference.com/w/cpp/language/adlで説明このサンプル考慮:引数依存ルックVS C++の通常のルックアップ

namespace A { 
     struct X; 
     struct Y; 
     void f(int); 
     void g(X); 
} 

namespace B { 
    void f(int i) { 
     f(i); // calls B::f (endless recursion) 
    } 
    void g(A::X x) { 
     g(x); // Error: ambiguous between B::g (ordinary lookup) 
       //  and A::g (argument-dependent lookup) 
    } 
    void h(A::Y y) { 
     h(y); // calls B::h (endless recursion): ADL examines the A namespace 
       // but finds no A::h, so only B::h from ordinary lookup is used 
    } 
} 

「ルック場合ADLルールが考慮されていないので、曖昧さが表示されますなぜ私が疑問に思って通常の非修飾ルックアップによって生成されるセットには、以下のいずれかが含まれます。ここ

その本体またはの一部としてのいずれかで、関数の定義に使用される名前のルール

からhttp://en.cppreference.com/w/cpp/language/unqualified_lookupおかげで説明したように修飾されていないルックアップによってB :: Gを見出すことができます関数がユーザ宣言またはグローバル名前空間のメンバである場合、名前が使用されるブロックが名前の使用前に検索され、そのブロックの開始前に囲まれているブロックが検索されます。関数本体であるブロックに到達します。次に、関数が宣言されている名前空間が考慮さADLのルールがあるなぜ、私の質問があるなどの名前を使用する関数の定義(必ずしも宣言)、そして囲む名前空間、

まで検索されますこの場合?

+0

理由を考慮しない理由を詳しく説明できますか? – cpplearner

+0

最初に、通常の非修飾ルックアップによって生成されたルックアップセットに次のいずれかが含まれている場合、引数依存ルックアップは考慮されません。 – FlashMcQueen

+0

1)クラスメンバーの宣言 2)ブロックスコープでの関数の宣言使用している宣言) 3)関数または関数テンプレートではない宣言(たとえば、関数オブジェクトや、名前が参照されている関数の名前と矛盾している別の変数) – FlashMcQueen

答えて

1

この場合、なぜADL(引数依存ルックアップ)ルールが考慮されるのですか?

関連する名前空間で一致する可能性があります。例えば:

void f(void*); 

namespace A { 
struct X; 
void f(X*); 
} 

int main() { 
    A::X* x = 0; 
    f(x); // A::f is the best match. 
} 

この機構はしばしばswap functionのために使用される:

std::swapは、(名前空間stdでないユーザ定義型の名前空間stdに特化されてもよいが、そのような特殊化は、ADLによって発見されていませんユーザー定義型の関連する名前空間)。 ユーザー定義型をスワップ可能にするための期待された方法は、型名と同じ名前空間に非メンバ関数のスワップを提供することです。詳細はSwappableを参照してください。このタイプの

任意の左辺または右辺の両方std::swapとユーザ定義swap() sが表示されているコンテキスト内で修飾されていない関数呼び出しswap()を使用して、いくつかの他のタイプの任意の左辺又は右辺と交換することができます。

+0

よろしくお願いします。 – FlashMcQueen

6

完全な引用は、通常の非修飾参照によって生成ルックアップセットは、次のいずれかが含まれている場合はまず、引数依存ルックアップが考慮されていない

です:

  1. の宣言
  2. ブロックスコープでの関数宣言(使用宣言ではありません)
  3. 宣言tハットは関数や関数テンプレートではありません。これが何を意味するのか、関数オブジェクトや名前が検索されるだ関数の名前と競合する他の変数)

は、修飾されていない検索は、上記の3つのいずれかの結果を生成する場合にのみADLは無視されていることです。クラスメンバーを扱っているわけではないので、関数はブロックスコープではなく名前空間のスコープで宣言され、我々は引き続き使用してADLを使う関数しか見つけません。

+0

ブロックスコープでの関数の宣言は何ですか(宣言は現在のスコープ内にありますか?) – FlashMcQueen

+0

@FlashMcQueen [ブロックスコープ]で宣言されている関数です(http://en.cppreference.com/w/cpp/language/scope#Block_scope) – NathanOliver

関連する問題