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

Copy-elision doesn't happen when using move

本文关键字:复制省 移动      更新时间:2023-10-16

为什么这个例子打印:

#include <iostream>
struct X
{
    X() = default;
    X(X const&) { std::cout << "copy-constructorn"; }
    X(X&&) { std::cout << "move-constructorn"; }
    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 调用移动构造函数

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

Copy elision 在第一种情况下有效,因为您正在从临时初始化赋值运算符的参数;可以省略临时,而是直接构造参数。用标准的话说,省略的标准之一是:

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

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