我对本地范围内的任何对象的默认行为是将其设置为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);我会尽量减少非功能性代码,因为这会增加...
在我看来,如果您想move
,则不声明为const
将是“常量正确”,因为您将(!)对其进行更改。这是意识形态上的矛盾。您不能移动任何东西并同时留在原地。您的意思是,在一定范围内,该对象将在一段时间内处于const
状态。在这种情况下,您可以声明对它的const引用,但是在我看来,这会使代码复杂化,并且不会增加任何安全性。甚至反之亦然,如果您不小心在std::move()
之后使用const引用对象,尽管看起来像使用const对象,也会出现问题。
一个有限的解决方法是const move构造函数:
[我相信,至少从标准move构造函数和非const
成员开始,不可能从mutable
对象中移出。但是,可能有一个const
自动本地对象和一个apply copy elision(即NRVO