代码之家  ›  专栏  ›  技术社区  ›  Felix

返回临时值rvalue作为值

  •  0
  • Felix  · 技术社区  · 7 年前

    所以,我有以下课程:

    class Foo {
    public:
        Bar &&bar() {
            return std::move(_bar);
        }
    private:
        Bar _bar;
    }
    

    我知道在以下上下文中使用此类是有效的:

    Bar bar;
    {
        Foo foo;
        bar = foo.bar(); // bar is move-assigned, as foo is still in scope
    }
    

    现在,我想知道的情况是:如果我直接从一个方法返回bar,而不事先存储它,会发生什么:

    Bar testFunc() {
        Foo foo;
        return foo.bar();
    }
    
    Bar test = testFunc();
    // is test now valid?
    

    我认为这在理论上应该是好的,因为 testFunc 返回由之前的rvalue构造的值 foo 已销毁-但如果编译器应用返回值优化,是否仍然是这种情况?

    我想我有点困惑这到底是怎么回事…

    1 回复  |  直到 7 年前
        1
  •  1
  •   AMA    7 年前

    测试现在有效吗?

    只要不访问moved from对象,代码就应该有效。

    但是,如果编译器应用 返回值优化?

    Bar testFunc() {
        Foo foo;          // Bar is constructed here
        return foo.bar(); // prvalue is move-constructed and copy elided
    }
    Bar test = testFunc(); // default ctor + move ctor (one copy elision)
    

    总共执行一次副本删除。

    将成员移出看起来像是代码的味道。不知道具体用法很难判断,但可能:

    Bar make_bar(const Foo& foo) {
        Bar bar;
        // init bar as needed
        return bar;
    }
    

    这样两个呼叫都会导致rvos。