引用崩溃?

通过试图解决这个问题 ,一些事情让我感到惊讶。 考虑下面的代码:

template <typename T> struct foo { foo(T const& x) : data(x) {} T data; }; 

看来我可以构造一个没有错误的foo<T const&>types的对象,假设的T const& const&被理解为T const&

似乎也被称为参考崩溃 ,但我从来没有听说过这个术语(见相关问题中的评论)。

这是普遍的吗? 这是标准吗?

在C ++ 03中,执行以下操作是不合法的

 typedef int &ref; ref &r = ...; // reference to reference! 

这经常会导致与编译真正严格或更老的C ++ 03编译器(GCC4.1以及Comeau 8/4/03不喜欢上述)的问题,因为标准函数对象绑定不处理“引用引用“的情况,偶尔会制造出这样的非法types。

在C ++ 0x中,这被称为“引用崩溃”,是的。 大多数当前的C ++ 03编译器通过追溯地应用该规则来做到这一点(即, T& ,其中T表示参考types再次是T )。 boost.call_traits库可以很容易地声明这样的函数参数,所以“参考引用”情况不会发生。

请注意, const没有任何影响。 在引用types上应用的const将被忽略。 所以即使编译器支持引用崩溃,以下是不合法的

 int const x = 0; // illegal: trying to bind "int&" to "int const"! ref const& r = x; 

据此,在C ++ 98中,对引用崩溃的支持有限:

在C ++ 98中,只有一个引用合并规则:T &&或对引用的引用,折叠到T&:

 void g(int & ri) {++ri;} // int& & -> int& void f(int & ri) {g(ri);} 

即使在那里,试图声明一个参考引用的variables也是非法的:

 int ben; int& bill(ben); // OK int & & bob(bill); // error C2529: 'bob' : reference to reference is illegal