これは、この質問の一種です。
#include <iostream>
struct type1 {};
struct type2 {};
void foo(type1 x)
{
std::cout << "foo(type1)" << std::endl;
}
template<typename T>
void bar() {
foo(T());
}
int main()
{
bar<type1>();
bar<type2>();
return 0;
}
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
上記のコードは、 infoo(type2)
のインスタンス化時に表示されません。それでも、コードはコンパイルされ、次の出力が生成されます。bar<type2>
main
foo(type1)
foo(type2)
foo(type2)
コンパイラは、でインスタンス化するときに利用可能bar<type2>
であることをどのように認識しますmain
か?
編集:テンプレートのインスタンス化中の過負荷解決がどのように機能するかについてもっと理解しようとしています。以下のコードを検討してください。
#include <iostream>
struct type1 {};
struct type2 {};
struct type3 {
operator type2() { return type2(); }
};
void foo(type1 x)
{
std::cout << "foo(type1)" << std::endl;
}
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
int main()
{
foo(type3());
return 0;
}
void foo(type3 x)
{
std::cout << "foo(type3)" << std::endl;
}
出力は
foo(type2)
より厳密な一致が利用可能であっても、その時点までコンパイラによって解析された唯一の候補であったためfoo(type3)
、呼び出しfoo(type3())
は解決されます。foo(type2)
ここで、次のコードについて考えてみます。
#include <iostream>
struct type1 {};
struct type2 {};
struct type3 {
operator type2() { return type2(); }
};
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
template<typename T>
void bar() {
foo(T());
}
int main()
{
bar<type3>();
return 0;
}
void foo(type3 x)
{
std::cout << "foo(type3)" << std::endl;
}
出力は
foo(type3)
つまり、呼び出しの時点で、表示されbar<type3>()
ているだけであってもfoo(type2)
、コンパイラfoo(type3)
は、より近い一致であるため、後で来るものを選択します。