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

uh *_*per 2 c++ move-semantics

让我们一起办理手续.

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

除了满足对象的不变量并且对象上的操作按其类型指定的操作之外,未指定的对象状态

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

一些用户认为这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.
Run Code Online (Sandbox Code Playgroud)

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

std::vector<int> v(10);
std::move(v).pop_back();
Run Code Online (Sandbox Code Playgroud)

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

std::vector<int> v(10);
std::cout << std::move(v).size();
auto v2 = std::move(v);
std::cout << v.size();
Run Code Online (Sandbox Code Playgroud)

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

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


有关参考,请参阅有关成员函数.begin()和std :: begin()的注释以及upvoted答案.

以下示例表明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();
}
Run Code Online (Sandbox Code Playgroud)

输出10.

Ser*_*eyA 6

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

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