這是一種關於 this的問題。超載分辨率解析爲一個不可見的功能
#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;
}
在上面的代碼foo(type2)
不在的bar<type2>
實例化在main
時可見。然而代碼編譯,併產生以下的輸出:
foo(type1)
foo(type2)
編譯器如何知道foo(type2)
實例中main
bar<type2>
時可用?
編輯:我想了解更多關於模板實例化過程中重載解析如何工作。考慮下面的代碼:
#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)
,後來因爲來這是一個更接近的匹配。
你的代碼用GCC 4.6編譯得很好。 – keveman
@keveman:引自[here](http://gcc.gnu.org/gcc-4.7/changes.html):'G ++現在正確地實現了兩階段查找規則,這樣在模板中使用的非限定名稱必須有一個適當的聲明可以在模板的定義點範圍內找到,或者通過在實例化處的參數相關查找來找到。 –
好的。它使用gcc 4.7失敗。謝謝。儘管我的結論是,在我的例子中,'foo(type3)'既不在模板定義的範圍內,也不在實例化點。這仍然是被調用的那個。 – keveman