引用崩溃?
通过试图解决这个问题 ,一些事情让我感到惊讶。 考虑下面的代码:
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