2017-03-07 8 views
7

せずに、名前空間内の関数を呼び出すと、私は次のテーマの多くのアプリケーションを見たことがありますか?私は、B::bar(a)だけがコンパイルされると予想していたでしょう。<code>boost::polygon</code>のソースコードを見てみると資格

関数が名前空間内に引数を持たない場合、これは発生しません。

+5

"Koenig lookup"と呼ばれる "ADL"(Argument Dependent Lookup)を検索します。 – nwp

+1

cppreferenceのADLリファレンス:http://en.cppreference.com/w/cpp/language/adl – NathanOliver

+0

ありがとう、それは速かった:) – vukung

答えて

6

§3.4.2でISO C++ 14標準によれば、関数呼び出しの後置表現は、通常の非修飾ルックアップ中に考慮していない未修飾-ID、他の名前空間である場合

それらの名前空間において、他に見えない名前空間範囲フレンド関数または関数テンプレート宣言は、で見つけることができる。検索に対するこれらの変更は、引数(およびテンプレートテンプレート引数の場合は、テンプレート引数の名前空間)のタイプによって異なります。

そして次

を関数呼び出しの各引数型Tについては、ゼロ以上の関連する名前空間のセットと考慮されるべきゼロ以上の関連するクラスのセットがあります。名前空間とクラスのセットは、関数の引数の型によって完全に決まります。

Tがクラス型(共用体を含む)の場合、そのクラスは次のとおりです。存在する場合にはそれがメンバーであるクラス。その直接的および間接的な基底クラスです。 関連する名前空間は、関連付けられたクラスの最も内側の名前空間です。

実はあなたも、関数名を囲むことにより、これを防ぐことができます。

(bar)(a); // doens't compile 

マインド

(B::bar)(a); // does compile 

ながらも、これが唯一であることを意味最も内側の名前空間に適用されることネームスペースを修飾する必要がある次の状況:

namespace B { 
    namespace C { 
    struct A {}; 
    } 

    void bar(const C::A& a) { ... } 
} 
関連する問題