在使用Microsoft VisualStudio 2008構建一個小示例程序的同時,我注意到傳遞給模板的類型的演繹有點奇怪。考慮下面的例子:爲什麼在推導類型時剝奪了模板參數的限定符?
template<class T>
void f(T v) {
x; // trigger a compile error
(void)v;
}
template<class T>
void g(T v) {
f(v);
}
void h() {
int i;
g<const int &>(i);
}
編譯使用cl /c foo.cpp
產生一個編譯錯誤(如預期)這個例子。有趣的是'T'模板參數的值。下面是2008年的VisualStudio打印:
mini.cpp(3) : error C2065: 'x' : undeclared identifier
mini.cpp(9) : see reference to function template instantiation 'void f<int>(T)' being compiled
with
[
T=int
]
mini.cpp(14) : see reference to function template instantiation 'void g<const int&>(T)' being compiled
with
[
T=const int &
]
注意如何在g
,參數的類型是const int &
但在f
它只是int
。很顯然,在實例化f
模板時,參考常量部分被刪除,同時推導出要使用的類型。調整例如當使得f
調用等
f<T>(v);
類型是在兩個f
g
和const int &
。這是爲什麼?這是指定的行爲?我暗中依靠v
函數參數的類型傳遞給f
,但顯然它不是。
'C++'模板+ MSVC++ =糟糕的組合。 – 2010-11-12 12:40:39
@Prasoon:GCC推導出相同的類型。當然,在GCC中,提問者的代碼會在'f'模板中觸發一個編譯錯誤,然後它會考慮實例化它,因爲GCC會正確執行兩階段編譯。 'x'不依賴於模板參數,所以應該在第一階段(如GCC)拒絕,而不是第二階段(如在MSVC中)。但是把'x'改成'v = 1;',很容易看到GCC沒有用'const int&'實例化'f',除非你在'g'中明確指定'f(v)'。 –
2010-11-12 12:45:31