私の期待に反して、このプログラムは動作します:
#include <iostream>
namespace a { struct item{}; }
namespace b { struct item{}; }
template<typename T>
void func(T t) { do_func(t); }
int main()
{
func(a::item{});
func(b::item{});
}
namespace a { void do_func(item) { std::cout << "a::func\n"; } }
namespace b { void do_func(item) { std::cout << "b::func\n"; } }
出力:
a::func
b::func
オンライン コンパイラによる検証:
のインスタンス化func<T>
が本体で発生する場合、main
私はそれを期待しa::do_func
、b::do_func
まだ宣言されていません。
これはどのように機能しますか?
アップデート
@Marc Claesenによると、上記が機能する理由は次のとおりです。
テンプレートのインスタンス化は、すべてのソースを読み取った後に実行されます
ただし、このコードが機能しないのはなぜですか。
#include <iostream>
template<typename T>
void func(T t) { do_func(t); }
int main()
{
func(1);
}
void do_func(int) { std::cout << "do_func(int)\n"; }
gcc-4.8を参照してください:
error: 'do_func' was not declared in this scope,
and no declarations were found by argument-dependent
lookup at the point of instantiation [-fpermissive]
error: call to function 'do_func' that is neither
visible in the template definition nor found by
argument-dependent lookup
そのため、機能させるには関数テンプレートと ADL の組み合わせが必要なようです。
しかし、私はなぜこれがそうであるのか理解していません..