如何知道编译器是否会使用复制省略以及我是否需要使用 std::move

问题描述 投票:0回答:1

在此示例代码中,我如何信任编译器进行非保证复制省略(在返回值优化的情况下):

struct X
{
   X() : size(10000), very_large_buffer(new char[size])
   {
   }

   X(const X& src) : size(src.size), very_large_buffer(new char[src.size])
   {
        memcpy(very_large_buffer, src.very_large_buffer, size);
   }

   X(X&& src) : size(src.size), very_large_buffer(src.very_large_buffer)
   {
   }

   char*   very_large_buffer = nullptr;
   size_t  size = 0;
};

X foo()
{
     X x;
     // some code
     return x;
}


X x = foo(); 

我检查了 g++ 11.4,它不调用复制或移动构造函数,这意味着复制省略发生。如果我在上面的 return 语句中添加 std::move :

return std::move(x);

然后调用移动构造函数。 但是,如果没有 std::move,如果编译器没有决定进行复制省略,则会调用复制构造函数,我想避免这种情况。

那么我怎样才能既:使用编译器不保证的复制省略(即不使用 std::move)并确保省略会发生并调用复制构造函数?

我的意思是:在我的示例中,我添加了调试打印并看到编译器执行了省略,但我无法对所有其他代码执行此操作。所以我最好有复制省略,但如果不能保证这一点,我会调用更多的移动构造函数,所以我需要 std::move。但如果我使用 std::move 复制省略将永远不会发生。那么非保证复制省略有什么用呢?

c++ copy-constructor move-constructor copy-elision
1个回答
0
投票
  1. “升级”到更高的 C++ 标准(至少 C++ 17)
  2. 使你的对象不可复制

第一个将保证优化,而第二个将确保您在不发生错误时得到错误。并捕获您不小心进行复制的所有其他实例。

© www.soinside.com 2019 - 2024. All rights reserved.