3

我想将一个对象移动到std::vectorusing 中std::vector::push_back()。这似乎是可能的,因为有一个std::vector::push_back(value_type&& val)功能。但是由于存在std::vector::push_back(value_type const & val)复制并且将成为压倒一切的调用,我需要将左值对象转换为右值。

这是怎么做到的?

例子:

struct X { int x; X(int x) : x(x) {} };

int main()
{
    std::vector<X> ax;
    X x(3);
    ax.push_back(x);  // <= Want to move x in to vector ax, not copy.
    return 0;
}

实际上,也许不可能?我问这个是因为在写完这个例子之后,我的新问题是:

  • 如果我搬进xax,价值是x.x多少?如果有一个显式的析构函数,当它离开作用域时X会发生什么?x
4

1 回答 1

4

只需使用std::move()

ax.push_back(std::move(x));

关于你的问题:

如果我确实将 x 移动到 ax 中,那么 xx 的值是多少?

在这种情况下,您的类X不包含显式声明的移动构造函数,因此编译器将生成一个对成员进行成员移动的构造函数X。由于X只有一个 type 成员int,并且移动 anint与复制它没有什么不同,因此x.x将具有与被移动之前相同的值。

如果 X 有一个显式的析构函数,当它离开作用域时 x 会发生什么?

如果X有一个用户声明的析构函数,那将禁止生成隐式移动构造函数——但不会禁止生成隐式复制构造函数。因此,这个函数调用:

ax.push_back(std::move(x));

将导致x复制ax. 无论如何,x超出范围时将被销毁,因为它具有自动存储持续时间 - 无论用户声明的析构函数是否存在。

通常,不应对已被移动的对象的状态做出假设,除非该状态是有效的(C++11 标准的第 17.6.5.15/1 段保证对于标准库)。

具体来说,这意味着唯一可以安全地处理已移动对象的函数是那些对该对象的状态没有任何先决条件的函数。通常,两个这样的函数是析构函数和(复制或移动)赋值运算符。

于 2013-05-19T17:36:23.833 回答