在std :: move(x)上执行一些操作

时间:2016-05-17 16:38:17

标签: c++ move-semantics

让我们办理手续。

  

17.3.28有效但未指明的状态[defns.valid]

     

除了对象之外没有指定的对象状态   满足不变量,对象上的操作按指定行为   对于它的类型

     

[示例:如果x类型的对象std::vector<int>是   在有效但未指定的状态下,可以调用x.empty()   无条件地,只有x.front()返回时才能调用x.empty()   假。 - 结束示例]

有些用户建议std::move(x).something()是荒谬的。但我无法理解std::move(x).something()y = std::move(x); y.something()之间的区别。观察:

// -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
std::vector<int> v;
v.pop_back();
// Error: attempt to access an element in an empty container.

现在我们想尝试一下荒谬的案例:

std::vector<int> v(10);
std::move(v).pop_back();

没有错误。这必须是每个人都在谈论的“有效但未指明”,但让我们继续前进。

std::vector<int> v(10);
std::cout << std::move(v).size();
auto v2 = std::move(v);
std::cout << v.size();

这会打印100。这并不太令人惊讶。 std::move只是一个演员,它实际上并不执行移动构造函数的工作。

我错过了什么或者std::move(x).something()仍然是非感性的(除非是无操作)?

供参考,请参阅Member function .begin() and std::begin()上的评论以及推荐的答案。

以下示例表明v未移至:

template< class C >
auto begin( C&& c ) -> decltype(c.begin())
{
    return c.begin();
}

int main()
{
    std::vector<int> v(10);
    std::vector<int>::iterator it3 = begin(std::move(v));
    std::cout << v.size();
}

输出10

2 个答案:

答案 0 :(得分:6)

std::move对该对象没有任何作用!它只是一个对象转换为ravlue,因此它可以被右值引用绑定。

对象的任何修改都由相应的移动构造函数或移动assingnment操作符完成。如果没有人被调用,根本没有任何事情发生。

答案 1 :(得分:0)

  

但我无法理解std::move(x).something()y = std::move(x); y.something()

之间的区别

使用(注意&之后的&& / const

struct S
{
    void foo() const & {std::cout << "l-value this\n"; }
    void foo() const && {std::cout << "r-value this\n"; }
};

你得到了:

S tmp;
std::move(tmp).foo(); // "r-value this

S x = std::move(tmp);
x.foo(); // "l-value this