下面的代码编译(gcc 4.7.2或icc 13)并生成“1 2”输出。这意味着const
限定符被删除,i。例如,f<int&>
的参数类型为int&
。
为什么会这样?据我了解,根据§14.3.1.4:
不应删除如果模板参数
T
的模板参数命名类型为“ cv1S
的引用”,则尝试创建类型“对 cv2T
“创建类型”对 cv12S
的引用“,其中 cv12 是cv-quali firs的联合 cv1 和 cv2 。冗余的cv-quali firs被忽略。
const
。这是代码:
#include <iostream>
using namespace std;
template <typename T>
void f(const T& t)
{
t++;
}
int main()
{
int a = 1;
cout << a;
f<int&>(a);
cout << ' ' << a << endl;
return 0;
}
答案 0 :(得分:4)
-std=c++98
时,GCC 4.7.2会不编译它。实际上,在C ++ 98(以及C ++ 03中)对引用的引用不会崩溃。
尝试实例化f<int&>
,其中T = int&
生成以下函数签名(这里我故意切换参数类型T
和const
说明符的位置,这是允许的,因为const T&
与T const&
}相同:
void f(int& const& t) // ERROR: reference to reference is illegal
上述内容在C ++ 98和C ++ 03中都不合法。一直以来,这是你从GCC 4.7.2得到的错误:
Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:15:14: error: no matching function for call to 'f(int&)'
source.cpp:15:14: note: candidate is:
source.cpp:5:6: note: template<class T> void f(const T&)
source.cpp:5:6: note: template argument deduction/substitution failed:
source.cpp: In substitution of 'template<class T> void f(const T&) [with T = int&]':
source.cpp:15:14: required from here
source.cpp:5:6: error: forming reference to reference type 'int&'
然而,如果使用-std=c++11
标志,则编译器在实例化模板时执行引用折叠:对左值引用的左值引用变为左值引用:
void f(int& const& t) == void f(int& t)
此处const
限定符被删除,因为它适用于引用,而不适用于引用的对象。由于无法重新分配引用,因此它们const
本质上是const
被认为是多余的并被删除的原因。有关解释,请参阅 this Q&A on SO 。
产生左值引用的左值引用,该引用解析为简单的左值引用。因此,右侧的签名被实例化。
以上是解决f<int&>(a)
调用的可行候选者,因此编译时没有错误。
答案 1 :(得分:4)
这是1770年有问题的报价似乎来源:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1770.html
14.3.1 - 模板类型参数
-4-如果模板参数T的模板参数命名类型&#34;左值 - 引用cv1 S,&#34;尝试创建类型&#34;(左值或右值)引用cv2 T&#34;创建类型&#34;左值 - 引用cv12 S,&#34;其中cv12是cv-qualifiers cv1和cv2的并集。如果template-argument命名一个类型&#34; rvalue-reference to cv1 S,&#34;尝试创建类型&#34;左值 - 引用cv2 T&#34;创建cv12 S的类型&#34;左值引用。&#34;如果template-argument命名一个类型&#34; rvalue-reference to cv1 S,&#34;尝试创建类型&#34; rvalue-reference to cv2 T&#34;创建cv12 S的类型&#34; rvalue-reference。&#34;冗余的cv限定符被忽略。
这是2118,其中引用已被删除:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
14.3.1 - 模板类型参数
-4-如果模板参数T的template-argument命名类型为
&#34;引用cv1 S&#34;,这是对类型A的引用,则尝试创建类型&#34;引用cv2 T&#34;&#34; lvalue-reference to cv T&#34;创建类型&#34;引用cv12 S&#34;,其中cv12是cv-qualifiers cv1和cv2的并集。冗余的cv限定符被忽略&#34;左值 - 引用A&#34;,同时尝试创建类型&#34; rvalue-reference to cv T&#34;创建类型T。
你所引用的内容似乎是过时的措辞。