より効率的な右辺値参照により返送されていますか?
-
12-09-2019 - |
質問
たとえばます:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
解決
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右辺値は、問題を説明し101 に、そしてどのように(参考資料読みすることをお勧めいたしますN)RVOはこれと対話するために起こります。
右辺値参照を返すあなたの場合は、他の場面で良いでしょう。あなたは、多くの場合、一時的に呼び出すgetAB()
機能を持っている想像してみてください。それは右辺値一時のためのconst左辺値参照を返す作るために最適ではないのです。あなたはこのようにそれを実装することができる。
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
move
自動ローカルでも一時的な右辺値でもないので、この場合はab
は、オプションではないことに注意してください。さて、のREF-修飾子の&&
は、第二の機能は、コピーの代わりに
Beta_ab ab = Beta().getAB();
他のヒント
このののビットの異なる文脈において、例えば、より効率的にすることができます:
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
は、通常のstd::min
のための62個の指示に対し、上記のコードのための54個の命令を生成します。しかし、-O0
では正規std::min
ため481に対して上記コードの518個の命令を生成します。