1. ホーム
  2. c++

[解決済み] rvalueの参照で返す方が効率的か?

2022-05-30 18:32:46

質問

例えば

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

どのように解決するのですか?

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

これは、lvalue参照の場合と同じように、ぶら下がった参照を返します。関数が戻った後、一時的なオブジェクトは破壊されます。を返すべきです。 Beta_ab を値で返すようにします。

Beta_ab
Beta::toAB() const {
    return Beta_ab(1, 1);
}

これで、ちゃんと一時的な Beta_ab オブジェクトを関数の戻り値に適切に移動しています。もしコンパイラが可能なら、RVO (return value optimization) を使って移動を完全に回避します。これで、次のようなことができるようになりました。

Beta_ab ab = others.toAB();

そして、テンポラリを ab に移動するか、あるいはRVOを実行して、移動またはコピーを完全に省略します。私はあなたが読むことをお勧めします BoostCon09 Rvalue リファレンス 101 を読んで、この問題と(N)RVOがどのように相互作用するかを説明することをお勧めします。


rvalueの参照を返すというあなたのケースは、他の場面でも良いアイデアでしょう。例えば getAB() 関数があるとします。この関数がrvalueのテンポラリに対してconst lvalueの参照を返すのは最適ではありません。このように実装することができます。

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};

なお move はオプションではありません。 ab はローカル自動でも一時的なrvalueでもないからです。さて、この ref-qualifierは && は、2番目の関数がrvalueのテンポラリに対して呼び出され、コピーではなく、次のような動きをすることを述べています。

Beta_ab ab = Beta().getAB();