当深度返回时,右值引用会中断

时间:2011-01-07 20:22:19

标签: c++ gcc c++11 reference rvalue

我在从超过1的深度传递返回的右值引用时遇到了问题。

struct Data {
 std :: vector <int> data;
 Data () {
  data .push_back (1);
 };

 Data (Data && d)
 : data (std :: move (d .data))
 {}
};

Data && foo () {
 Data d;
 return std :: move (d);
}

Data && bar () {
 return std :: move (foo ()); // Crashes in autogenerated code
}

Data && baz () {
 return foo (); // Crashes in Data move constructor.
}

Data && bop () {
 Data d = foo ();
    return std :: move (d); // Crashes in autogenerated code.
}

int main () {
 Data d_foo = foo (); // This is fine.
 Data d_bar = bar (); // Crash.
 Data d_bar = baz (); // Crash.
 Data d_bop = bop (); // Crash.
}

我认为std :: vector正在被双重释放。我正在使用g ++(Ubuntu / Linaro 4.4.4-14ubuntu5)4.4.5

以上代码是否适合您?我做错了还是库或编译器中有错误?

如果(天堂冒犯)它是编译器(gcc中还有其他已知的C ++ 0x错误),有人可以告诉我是否有一种安全的方法来升级或修补ubuntu上的gcc?我之前尝试过但是陷入了一堆不受支持的包裹。

非常感谢。

3 个答案:

答案 0 :(得分:6)

从函数返回rvalue引用很少有意义(异常std :: move),因为引用可能绑定到临时或堆栈上的对象,就像你的情况一样,当你返回它时,对象就消失了

编辑:

Data && foo () {
 Data d;
 return std :: move (d);
}
超出范围时,

d被销毁,因此您将返回悬空参考。

答案 1 :(得分:5)

您不返回右值引用,而是返回一个值,然后由调用者将其作为右值引用。您应该只有Data foo(),而不是Data&& foo()。任何这些作品都是纯粹的巧合,因为它是未定义的行为。

答案 2 :(得分:0)

除了将常规引用/指针返回到本地对象之外,您不能指望将&&返回到本地对象有任何好处。

您应该按价值返回。在C ++ 03下,允许编译器优化远离调用复制构造函数的情况。在C ++ 0x中,这意味着(如果无法优化复制 - 例如编译器在从不同分支返回不同对象时不管理它),将调用移动构造函数而不是复制构造函数(如果可用)从函数中获取值。

据我所知,移动语义应该在安全的地方自动启动,并且rvalue引用参数类型允许您确定参数是否是rvalue(您可以显式移动的)或不是。