以下代码显示,如果使用引用类型(例如const
)实例化采用ref-to - int&
参数的模板,则参数不是const
:
#include <iostream>
template<typename T>
void f(const T& arg) // arg isn't const if T is a reference type
{
arg = -1;
}
int main()
{
int x = 0;
f<int&>(x); // instantiate f with reference type
std::cout << x << '\n'; // prints -1 under gcc, clang, and msvc
}
这里发生了什么?
我的猜测是arg
的初始类型是int & const &
,并且它会以某种方式转换为int&
。如果是这样的话,就标准而言,究竟是怎么发生的呢?如果那不是正在发生的事情,那是什么?
答案 0 :(得分:2)
感谢Vlad from Moscow对C++: template function with explicitly specified reference type as type parameter的回答,我相信const
- 消失的关键是8.3.2 / 1,其中说:
在声明T D中,其中D具有任何一种形式
&安培; 属性说明符-seqopt D1
&安培;&安培; 属性说明符-seqopt D1
并且声明T D1中的标识符的类型是 “ derived-declarator-type-list T,”然后是D的标识符的类型 是“ derived-declarator-type-list 对T的引用”。可选 attribute-specifier-seq 属于引用类型。 CV-合格 除非引入了cv限定符,否则引用的格式不正确 通过使用 typedef-name (7.1.3,14.1)或 decltype-specifier (7.1.6.2),在这种情况下忽略cv限定符。
我鼓舞了相关的文字。 (我想格式化整个段落,因为它在标准中,但我无法弄清楚如何获得正确的缩进并添加下标。)
一旦const
消失,正常参考折叠将照常开始。
答案 1 :(得分:0)
const T
是T
类型的对象,其值无法修改。但是,当T
是引用类型时,const
修饰符是多余的,因为初始化后引用无法更改 - 它们始终引用同一对象。因此,当const T
只是T=int&
(在这种情况下为T
)时int&
。因此,f<int&>
所采用的论点是对int&
的左值引用,而c ++ 11的折叠规则只是int&
。