使用移动时不会发生复制省略

时间:2015-03-09 14:09:42

标签: c++

为什么打印这个例子:

#include <iostream>

struct X
{
    X() = default;
    X(X const&) { std::cout << "copy-constructor\n"; }
    X(X&&) { std::cout << "move-constructor\n"; }

    X& operator=(X)
    {
        return *this;
    }
};

int main() 
{
    X x, y;
    std::cout << "assign from prvalue calls the ";
    x = X{};
    std::cout << "\nassign from xvalue calls the ";
    x = std::move(y);
}
  

从prvalue分配调用   从xvalue赋值调用move-constructor

X{}std::move(y)都是rvalues,那么为什么只分配给X{}导致复制省略?

1 个答案:

答案 0 :(得分:11)

复制省略在第一种情况下起作用,因为您从临时初始化赋值运算符的参数;临时可以省略,直接构造参数。用标准来说,elision的标准之一是:

  

当一个未绑定到引用的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动

在第二种情况下,您不是从临时对象,而是从现有对象初始化它。它已经在与目标不同的位置构建,因此无法完成上述优化。