如果我有
template<class T>
void foo(T &) { }
并将其称为foo((const int)5)
,假设参数为const int
,为什么编译器不会自动推断T
为const int
?< / p>
答案 0 :(得分:8)
根据C ++ 03标准,第2.12.1.2节,整数文字的类型为int
,而不是const int
。
整数文字的类型取决于其形式,值和后缀。 如果它是十进制且没有后缀,则它具有第一种类型 其值可以表示为:int,long int; ...
<强>更新强>
另一种相关类型扣除规则可能是14.8.2.1.2。
如果P不是参考类型:
[...]
- 如果A是cv限定类型,则是A类型的顶级cv限定符 因类型扣除而被忽略。
如果P是cv限定类型,则是P类型的顶级cv限定符 被忽略的类型扣除。
如果P是引用类型,则P引用的类型用于类型 扣。
OP提供的代码甚至不会编译,因为将非const引用绑定到rvalue是非法的。
答案 1 :(得分:7)
如果给出了const类型,它确实如此。 Rvalues(C ++ 11中的prvalues)
然而,即使你试图说,非类型的类型也从未获得cv认证
它们是:表达式((const int)5)
的类型为int
。推理
这里的cv资格只适用于对象和临时对象
非类型不是对象,而是纯值; cv资格不能
申请,因为没有什么是const
或volatile
。
如果你写:
int const i = 42;
foo( i );
,您的模板将使用T = int const
进行实例化。 (和你一样
写了它,代码不应该编译,因为推导出的类型
是int
,因此该函数采用int&
,但不能
用右值初始化。)