0

从大于 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?我以前尝试过,但陷入了一堆不受支持的包中。

非常感谢。

4

3 回答 3

6

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

编辑:

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

d超出范围时被销毁,因此您将返回悬空引用。

于 2011-01-07T20:27:31.553 回答
5

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

于 2011-01-07T20:33:46.190 回答
0

You can't expect any good from returning a && to a local object any more than from returning a regular reference / pointer to a local object.

You should return by value. Under C++03 it is a situation where the compiler is allowed to optimize away calls to copy constructor. In C++0x this means that (if the copying can't be optimized away - e.g compilers don't manage it when returning a different object from different branches) the move constructor will be invoked instead of a copy constructor (if available) to get the value out of the function.

As far as I can understand, move semantics is supposed to kick in automatically in places where it is safe, and rvalue reference parameter types allow you to determine if the argument is a rvalue (something you can explicitly move) or not.

于 2011-01-08T10:29:57.213 回答