参考崩溃?

时间:2010-09-22 16:02:08

标签: c++

通过尝试解决this problem,有些事让我感到奇怪。请考虑以下代码:

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

似乎我可以构造一个foo<T const&>类型的对象而没有错误,假设的T const& const&被理解为T const&

这似乎也被称为引用崩溃,但我之前从未听过这个术语(请参阅链接问题中的评论)。

这种情况普遍存在吗?这是标准吗?

2 个答案:

答案 0 :(得分:20)

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

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

这经常会导致人们使用真正严格或较旧的C ++ 03编译器进行编译(GCC4.1以及Comeau 8/4/03不喜欢上述内容),因为标准函数对象绑定器不处理“参考参考”的情况,偶尔会造成这种非法类型。

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

请注意,const没有任何效果。默认情况下会忽略应用于引用类型的const。因此,即使编译器支持引用折叠,以下内容也不合法

int const x = 0;

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

答案 1 :(得分:5)

根据this,在C ++ 98中,对参考折叠的支持有限:

  

在C ++ 98中,只有一个引用   崩溃规则:T&amp; &安培;或参考   参考,折叠到T&amp;:

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

即使在那里,尝试声明一个引用引用的变量也是非法的:

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