这是对这个问题的一种跟进。
#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>()
,即使 onlyfoo(type2)
是可见的,编译器仍然会选择foo(type3)
稍后出现的,因为这是更接近的匹配。