GCC 4.7.2 确实not编译此标志时-std=c++98
已指定。事实上,在 C++98(以及 C++03)中,对引用的引用不会崩溃。
尝试实例化f<int&>
, where 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
被认为是多余的并被删除。看关于 SO 的问答以获得解释。
这会产生一个对左值引用的左值引用,该左值引用解析为简单的左值引用。因此,右侧的签名被实例化。
以上是解决这一呼吁的可行候选者f<int&>(a)
因此,它编译时没有错误。