これは、テンプレート引数として指定することにより、関数テンプレートを明示的にインスタンス化しようとするためです。テンプレートの場合、呼び出し時にその名前の関数テンプレートが表示されていれば、ADL は機能します。この可視関数テンプレートは、ADLのトリガーを支援するだけであり (実際には使用されない場合があります)、他の名前空間で最も一致するものを見つけることができます。get
0
ADLをトリガー(または有効化)する関数テンプレートには、定義が必要ないことに注意してください。
namespace M
{
struct S{};
template<int N, typename T>
void get(T) {}
}
namespace N
{
template<typename T>
void get(T); //no need to provide definition
// as far as enabling ADL is concerned!
}
void f(M::S s)
{
get<0>(s); //doesn't work - name `get` is not visible here
}
void g(M::S s)
{
using N::get; //enable ADL
get<0>(s); //calls M::get
}
ではg()
、名前はN::get
を呼び出すときに ADL をトリガーしますget<0>(s)
。
デモ : http://ideone.com/83WOW
C++ (2003) セクション §14.8.1/6 の読み取り、
[注: 単純な関数名の場合、呼び出しのスコープ内で関数名が表示されない場合でも、引数依存のルックアップ (3.4.2) が適用されます。これは、呼び出しが関数呼び出し (3.4.1) の構文形式のままであるためです。ただし、明示的なテンプレート引数を持つ関数テンプレートが使用されている場合、呼び出しの時点でその名前の関数テンプレートが表示されていない限り、呼び出しは正しい構文形式になりません。そのような名前が表示されない場合、呼び出しは構文的に整形式ではなく、引数依存のルックアップは適用されません。そのような名前が表示されている場合、引数に依存するルックアップが適用され、追加の関数テンプレートが他の名前空間で見つかる場合があります。
[例:
namespace A {
struct B { };
template<int X> void f(B);
}
namespace C {
template<class T> void f(T t);
}
void g(A::B b) {
f<3>(b); //ill-formed: not a function call
A::f<3>(b); //well-formed
C::f<3>(b); //ill-formed; argument dependent lookup
// applies only to unqualified names
using C::f;
f<3>(b); //well-formed because C::f is visible; then
// A::f is found by argument dependent lookup
}
—例の終わり] —終わりのメモ]