c++ - 我应该让我的局部变量是常量还是可 move ?

标签 c++ c++17 move-semantics const-correctness

我对本地范围内任何对象的默认行为是使其 const .例如。:

auto const cake = bake_cake(arguments);

我尽量减少非功能性代码,因为这会增加可读性(并为编译器提供一些优化机会)。所以在类型系统中也反射(reflect)这一点是合乎逻辑的。

然而,使用 move 语义,这会产生问题:如果我的 cake 怎么办?很难或不可能复制,我想在完成后将其传递出去?例如。:
if (tastes_fine(cake)) {
  return serve_dish(cake);
}

据我了解 copy elision rules不保证 cake拷贝将被省略(但我不确定)。

所以,我必须搬家 cake出去:
return serve_dish(std::move(cake)); // this will not work as intended

但是那个std::movedo nothing useful ,因为它 ( correctly ) 不会转换 Cake const&Cake&& .即使对象的生命周期已接近尾声。我们不能从我们 promise 不会改变的东西中窃取资源。但这会削弱常量正确性。

那么,我怎样才能拥有我的蛋糕并吃掉它呢?

(即我怎样才能拥有常量正确性并从 move 语义中受益。)

最佳答案

我相信不可能从 const move 对象,至少具有标准的 move 构造函数和非 mutable成员。但是,可能有 const自动本地对象和 apply copy elision (即 NRVO)。在您的情况下,您可以按如下方式重写原始函数:

Cake helper(arguments)
{
   const auto cake = bake_cake(arguments);
   ...  // original code with const cake
   return cake;  // NRVO 
}

然后,在您的原始函数中,您可以调用:
return serve_dish(helper(arguments));

由于 helper 返回的对象已经是一个非常量的右值,它可以被移出(如果适用,它可以再次被省略)。

Here是演示这种方法的现场演示。请注意,在生成的程序集中没有调用复制/move 构造函数。

关于c++ - 我应该让我的局部变量是常量还是可 move ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61987624/

相关文章:

c++ - 尽管传入了 PATH 变量,但 execve(...) 不执行程序

c++ - 整数比较运算符是否在 C++ 中短路?

c++ - `std::pmr::monotonic_buffer_resource` : why the `dynamic_cast` ?

c++ - 另一个类范围内的类模板参数类型推导

C++11 - 在构造函数中 move 基本数据类型?

c++ - move 语义 == 自定义交换功能已过时?

c++ - 错误 : initializer fails to determine size of ‘K’

c++ - 从 Main 方法调用函数

c++ - 我无法按类型访问使用 forward_as_tuple 创建的元组中的元素

C++11:std::move() 调用参数列表