在使用 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 &
。这是为什么?这是指定的行为吗?我 secret 地依赖传递给 f
的 v
函数参数的类型,但显然不是。
最佳答案
答案是虽然变量 v
的类型是 const int &
,但是 expression v
是一个类型为 const int
的左值表达式。
litb 提供了文本 (5/6):“如果一个表达式最初具有“对 T 的引用”类型(8.3.2、8.5.3),则在任何进一步分析之前将类型调整为“T”,该表达式指定由引用表示的对象或函数,并且该表达式是一个左值。”
“参数”是“函数调用表达式中由括号包围的逗号分隔列表中的表达式”(1.3.1)。所以在 14.8.2.1 中:
- “调用的相应参数类型(称之为A)”是
const int
。 - “如果 A 是 cv 限定类型,则类型推导将忽略 A 类型的顶级 cv 限定符”(因此,
int
)。 - “推导过程试图找到使推导的 A 与 A 相同的模板参数值”(所以 T 是
int
)
关于c++ - 为什么在推导类型时去除模板参数的限定符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4164451/