web-dev-qa-db-ja.com

右辺値参照による戻りはより効率的ですか?

例えば:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
118
Neil G
_Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
_

これは、左辺値参照の場合と同様に、ぶら下がり参照を返します。関数が戻った後、一時オブジェクトは破壊されます。次のように、値で_Beta_ab_を返す必要があります

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

現在、一時的な_Beta_ab_オブジェクトを関数の戻り値に適切に移動しています。コンパイラーができる場合、RVO(戻り値の最適化)を使用して、移動を完全に回避します。これで、次のことができます

_Beta_ab ab = others.toAB();
_

そして、テンポラリーをabに移動するか、RVOを実行して移動またはコピーを完全に省略します。 BoostCon09 Rvalue References 101 をお読みになることをお勧めします。


右辺値参照を返す場合は、他の場合には良い考えです。一時的に頻繁に呼び出すgetAB()関数があるとします。右辺値の一時変数に対してconst左辺値参照を返すのは最適ではありません。このように実装できます

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

moveはローカル自動値でも一時的な右辺値でもないため、この場合のabはオプションではありません。さて、ref-qualifier_&&_は、2番目の関数が右辺値テンポラリーで呼び出され、コピーではなく次の移動を行うことを示します

_Beta_ab ab = Beta().getAB();
_
216

canより効率的です。たとえば、少し異なるコンテキストで:

template <typename T>
T&& min_(T&& a, T &&b) {
    return std::move(a < b? a: b);
}

int main() {
   const std::string s = min_(std::string("A"), std::string("B"));
   fprintf(stderr, "min: %s\n", s.c_str());
   return 0;
}

興味深い観察として、私のマシンでclang++ -O3は、上記のコードに対して54個の命令を生成しますが、通常のstd::min。ただし、-O0上記のコードに対して518命令を生成しますが、通常のstd::min

3
wonder.mice