通过尝试解决this problem,有些事让我感到奇怪。请考虑以下代码:
template <typename T>
struct foo
{
foo(T const& x) : data(x) {}
T data;
};
似乎我可以构造一个foo<T const&>
类型的对象而没有错误,假设的T const& const&
被理解为T const&
。
这似乎也被称为引用崩溃,但我之前从未听过这个术语(请参阅链接问题中的评论)。
这种情况普遍存在吗?这是标准吗?
答案 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