可能重复:
从右值参数推导出对 const 的引用
如果我有
template<class T>
void foo(T &) { }
我称它为foo((const int)5)
,鉴于参数是 a const int
,为什么编译器不自动推断T
为const int
?
可能重复:
从右值参数推导出对 const 的引用
如果我有
template<class T>
void foo(T &) { }
我称它为foo((const int)5)
,鉴于参数是 a const int
,为什么编译器不自动推断T
为const int
?
根据 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 类型,它确实如此。然而,具有非类类型的右值(C++11 中的右值)永远不是 cv 限定的,即使您试图说它们是:表达式((const int)5)
具有 type int
。这里的推理是 cv 限定只适用于对象,非类类型的临时对象不是对象,而是纯值;cv-qualifications 不能适用,因为没有什么是const
or volatile
。
如果你写:
int const i = 42;
foo( i );
,您的模板将使用T = int const
. (正如你写的那样,代码不应该编译,因为推导的类型是int
,所以函数需要一个int&
,它不能用右值初始化。)