【发布时间】:2011-05-09 01:05:08
【问题描述】:
在使用 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”模板参数的值。这是 VisualStudio 2008 打印的内容:
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 模板时推断要使用的类型时,引用到 const 的部分被剥离了。当调整示例以便f 被调用时,就像
f<T>( v );
f 和 g 中的类型都是 const int &。这是为什么?这是指定的行为吗?我偷偷依赖 v 函数参数的类型传递给 f 但显然不是。
【问题讨论】:
-
C++模板 + MSVC++ = 错误组合。 -
@Prasoon:GCC 推断出相同的类型。当然,在 GCC 中,发问者的代码在模板中
f触发编译错误,然后再考虑实例化它,因为 GCC 正确地进行了两阶段编译。x不依赖于模板参数,因此应该在第一阶段(如在 GCC 中)被拒绝,而不是在第二阶段(如在 MSVC 中)。但是将x改为v = 1;,很容易看出GCC不会用const int&实例化f,除非你在g中明确指定f<T>(v)。
标签: c++ visual-studio visual-studio-2008 templates