c++ - 转换为右值引用可防止复制省略

标签 c++ rvalue-reference move-constructor copy-elision

我阅读了更多相关文章,但没有一个答案能够澄清我的疑虑。为什么在下面的代码中,仅当没有转换为右值引用时才会进行优化,否则将调用移动(无论是否提供)或复制(如果没有提供移动构造函数)构造函数。

struct Clasa{
    Clasa(){
        std::cout << "Default" << std::endl;
    }
    Clasa(const Clasa& clasa){
        std::cout << "Copy" << std::endl;
    }
    Clasa(Clasa&& clasa){
        std::cout << "Move" << std::endl;
    }
    ~Clasa(){
        std::cout << "Destructor" << std::endl;
    }
};

int main(){
    Clasa c = (Clasa&&)Clasa();//no optimization
    Clasa d = Clasa();//move/copy elision
} 

最佳答案

在第一种情况下,Clasa c = (Clasa&&)Clasa(); 临时物化发生在您显式绑定(bind)对纯右值的引用(Class()),因此这里没有省略。这可以从temporary materialization看出:

Temporary materialization occurs in the following situations:

  • when binding a reference to a prvalue;

现在来看Clasa d = Clasa();的第二种情况。

C++17 及以上版本

从 C++17 开始有 mandatory copy elision 。这意味着标准强制要求将对象直接构造到存储中,否则它将被复制/移动到存储中。这本质上意味着这里不会观察到复制/移动调用。

C++17 之前版本

但在 C++17 之前,这可能会导致创建一个临时对象,使用该临时对象来复制初始化。同样更详细地解释了here .

关于c++ - 转换为右值引用可防止复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77383403/

相关文章:

c++ - OpenCV 3.0 中的事件轮廓模型

c++ - 如何测量代码更改的电源效率增加或减少

c++ - 右值引用是否有reference_wrapper<>?

c++11 - 移动构造函数不适用于成员变量?

C++0x 移动构造函数陷阱

c++ - 当代码编译正确时,你能确定所有模板类型都是正确的吗?

c++ - dynamic_cast<> 将变量参数传递给模板

c++ - 不使用 boost::asio::ip::tcp::socket 调用移动构造函数

c++ - 有没有办法编写一个将 l-val ref 或 r-val reference 作为输入参数的函数?

c++ - 手动选择右值或左值类型的重载函数