我应该让我的局部变量为const还是可移动的?

问题描述 投票:4回答:3

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

auto const cake = bake_cake(arguments);

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

但是,使用移动语义,这会产生问题:如果我的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::move将为do nothing useful,因为它(correctly)不会将Cake const&强制转换为Cake&&。即使对象的寿命非常接近其寿命。我们不能从我们承诺不会改变的东西中窃取资源。但这会削弱const正确性。

所以,我怎么也可以吃我的蛋糕?

(即,如何具有常量正确性,还可以从移动语义中受益。)

我对本地作用域中任何对象的默认行为是使其成为常量。例如:auto const cake = bake_cake(arguments);我会尽量减少非功能性代码,因为这会增加...

c++ c++17 move-semantics const-correctness
3个回答
0
投票

在我看来,如果您想move,则不声明为const将是“常量正确”,因为您将(!)对其进行更改。这是意识形态上的矛盾。您不能移动任何东西并同时留在原地。您的意思是,在一定范围内,该对象将在一段时间内处于const状态。在这种情况下,您可以声明对它的const引用,但是在我看来,这会使代码复杂化,并且不会增加任何安全性。甚至反之亦然,如果您不小心在std::move()之后使用const引用对象,尽管看起来像使用const对象,也会出现问题。


0
投票

一个有限的解决方法是const move构造函数:


0
投票

[我相信,至少从标准move构造函数和非const成员开始,不可能从mutable对象中移出。但是,可能有一个const自动本地对象和一个apply copy elision(即NRVO

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