1. ホーム
  2. c++

[解決済み] なぜADLは関数テンプレートを見つけられないのですか?

2023-05-10 16:08:34

質問

C++ の仕様のどの部分が、引数依存の検索が、関連する名前空間のセットで関数テンプレートを見つけることを制限していますか? 言い換えれば、なぜ最後の呼び出しが main の最後の呼び出しがコンパイルに失敗するのはなぜでしょうか?

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++スタンダード03 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
}