为什么不将模板类型参数推断为'const'?

Meh*_*dad 7 c++ templates const type-parameter

可能重复:
从rvalue参数推断对const的引用

如果我有

template<class T>
void foo(T &) { }
Run Code Online (Sandbox Code Playgroud)

我这样称呼它foo((const int)5),因为参数是const int,为什么不编译器自动推断Tconst int

And*_*rey 8

根据C++ 03 Standard,第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是非法的.

  • 你的评论尽可能好,但它们不适用于他的例子.他没有使用积分文字进行实例化,而是使用强制转换表达式.并且只有第二个引用的最后一点适用,因为在他的情况下,`P`是一个引用类型(没有顶级const).他的代码没有编译(或者在一个破坏的编译器中导致`T = int`)的原因是因为表达式`((int const)5)`是非类类型的rvalue,而rvalues是非类类型没有cv-qualifiers(即使你明确地说它们应该). (2认同)

Jam*_*nze 7

如果它被赋予const类型,它确实如此.然而,具有非类类型的Rvalues(C++ 11中的prvalues)永远不会被cv限定,即使你试图说它们是:表达式((const int)5)有类型int.这里的推理是,cv资格只适用于对象,非类型的临时数不是对象,而是纯值; cv资格不能适用,因为没有什么是constvolatile.

如果你写:

int const i = 42;
foo( i );
Run Code Online (Sandbox Code Playgroud)

,您的模板将实例化T = int const.(正如你所写的那样,代码不应该编译,因为推导的类型是int,所以函数采用a int&,不能用rvalue初始化.)