[英]Passing rvalue to function that may not use it
可以说我有一个类定义如下:
class Foo {
public:
...
bool add_widget(Widget&& w) {
if (some condition) {
return false;
}
container.push_back(std::move(w));
return true;
}
private:
std::deque<Widget> container;
}
我把课程称为如下:
int main(int argc, char* argv[]) {
Foo f;
Widget w;
if (!f.add_widget(std::move(w))) {
// Can I still use w here?
}
}
如果some condition
为真,则Widget w
将不会添加到Foo的container
。 在main()
,当add_widget()
返回指示添加不成功时,我仍然可以使用w
,还是应该总是假设它已被移动并且不再可用?
编写像add_widget()
这样的函数是不好的做法,它接受一个r值引用但实际上可能不会移动它的参数?
如果“some condition”的计算结果为true
则add_widget
成员函数将在输入w
以deque
方式移动之前返回。 因此,您可以安全地使用w
in main。
请记住, std::move
实际上并不移动对象。 std::move
只不过是一个类型转换。
即使w
被移动,那么main中的w
也将处于有效但未指定的状态。
这意味着您可以对w
执行任何没有先决条件的操作。 如果有一个你想要执行前置条件的操作,那么你必须间接执行该操作,因为你不知道对象的未指定状态是否满足前提条件。
在这种情况下使用widget非常好,因为它的状态不会以任何方式改变。
但是,您应该只依赖于此行为,如果您在函数描述中明确地记录它,并且因此即使在将来重构的情况下也愿意承诺该保证。
有人可能会争论,这是否过于聪明和/或令人惊讶,但实际上它与依赖std::vector::push_back()
等函数的强异常保证并没有太大区别。
从c ++ 17开始,这个习惯用法在标准库中使用。
看看第二种形式的std::map::try_emplace
参考: http : //en.cppreference.com/w/cpp/container/map/try_emplace
请注意,键类型(实际上在某些情况下,用于构造值的参数)是r值引用,但如果键尚未存在,它们只会移动到映射中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.