ホームページ >バックエンド開発 >C++ >明示的にインスタンス化された関数テンプレートで引数依存検索 (ADL) が失敗するのはなぜですか?

明示的にインスタンス化された関数テンプレートで引数依存検索 (ADL) が失敗するのはなぜですか?

DDD
DDDオリジナル
2024-12-11 04:20:10574ブラウズ

Why Does Argument Dependent Lookup (ADL) Fail with Explicitly Instantiated Function Templates?

ADL および関数テンプレートの検索

関数テンプレートは C プログラミングで重要な役割を果たし、コードの再利用と汎用機能を可能にします。ただし、引数依存検索 (ADL) を使用して特定の名前空間内の関数テンプレートを検索する場合、微妙な制限が発生します。

次のコードに示すように、明示的なテンプレート引数を使用して関数テンプレートを呼び出そうとすると、この問題が現れます。スニペット:

namespace ns {
    struct foo {};
    template<int i> void frob(foo const&amp;) {}
    void non_template(foo const&amp;) {}
}

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。