ADL および関数テンプレートの検索
関数テンプレートは C プログラミングで重要な役割を果たし、コードの再利用と汎用機能を可能にします。ただし、引数依存検索 (ADL) を使用して特定の名前空間内の関数テンプレートを検索する場合、微妙な制限が発生します。
次のコードに示すように、明示的なテンプレート引数を使用して関数テンプレートを呼び出そうとすると、この問題が現れます。スニペット:
namespace ns { struct foo {}; template<int i> void frob(foo const&) {} void non_template(foo const&) {} } int main() { ns::foo f; non_template(f); // This is fine. frob<0>(f); // This is not. }
この失敗の背後にある理由は、C 標準の特定の句にあります。 C 標準 03 14.8.1.6 に従って、明示的なテンプレート引数を使用して関数テンプレートを呼び出す場合、その名前の関数テンプレートが呼び出し時点で表示されていない限り、ADL は適用されません。
上の例では、 frob<0>(f); の場合、現在のスコープに frob という名前の関数テンプレートが表示されません。と呼ばれます。したがって、ADL はトリガーされず、コンパイラは目的の関数テンプレートを見つけることができません。
この制限を回避するには、以下に示すように、関数テンプレートの前に名前空間を明示的に指定できます。
ns::frob<0>(f);
この場合、関数テンプレートは含まれている名前空間から直接呼び出されるため、ADL は必要ありません。
次のコード例関数テンプレートを使用した ADL の動作をさらに示します。
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 }
この例では、関数テンプレート f は名前空間 A と C の両方で定義されています。が作成されると、コンパイラはまず現在のスコープをチェックし、表示可能な f テンプレートを見つけません。その後、ADL が適用されますが、 f は非修飾名であるため、他の名前空間で関数テンプレートを見つけることができません。
名前空間 C からテンプレートを呼び出すには、C::f または using ディレクティブで名前を明示的に修飾する必要があります。コードで示されているように。
以上が明示的にインスタンス化された関数テンプレートで引数依存検索 (ADL) が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。