繁体   English   中英

将rvalue传递给可能不使用它的函数

[英]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”的计算结果为trueadd_widget成员函数将在输入wdeque方式移动之前返回。 因此,您可以安全地使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM