2012-04-19 10 views
1

std::reverse()のコンビニエンスラッパーを実装するには、これはC++ 11のrvalue-referencesとmove semanticsを使用する正しい方法ですか?C++ 11 std :: reverse()のコンビニエンスラッパー

template <class BIDirContainer> inline BIDirContainer&& reverse(BIDirContainer a) { 
    std::reverse(begin(a), end(a)); 
    return std::move(a); 
} 

コードは、私のテストケースで動作しますが、私はその程度の性能が不明午前:私はここ&&を使用するか、それがunneccesaryである必要がありますか?

答えて

2

私はそれを行うための正しい方法は、あなたの関数から値で返すことだと思います。

template <class BIDirContainer> inline BIDirContainer reverse(BIDirContainer a) { 
    std::reverse(begin(a), end(a)); 
    return a; 
} 

し、それが1つを持っていない場合BIDirContainer移動コンストラクタを与えます。そして、表現のこの種:

BIDirContainer x = ...; 
BIDirContainer backwards{reverse(x)}; 

backwardsにあなたのreverse機能が一時的にaの内容を移動する必要があります。あなたが逆のコピーを作成したい場合は

+0

STLコンテナ(既にコンストラクタをサポートしています)では正しい方法は '&&'も 'std :: move'も使用しないでしょうか? –

+1

@Nordlöwはあなたの関数ではどちらも使用しません。あなたがムーブコンストラクタを実装している場合にのみクラスで使用してください。 C++ 11のコンテナを使用している場合は、何もする必要はありません。 – juanchopanza

3

(rvalue)参照で返信すると、aはローカルオブジェクトなので、ダングリングリファレンスが返されます。価値によって戻り、すべてが「うまくいく」べきです。

+0

私はまだ 'std :: move'を使うべきですか?ありがとう。 –

+0

@Nordlöw移動の必要はありません。おそらく 'BIDirContainer'には移動コンストラクタの実装がありません。以下の回答を参照してください。 – juanchopanza

+0

C++ 11では、ローカルオブジェクト(この例では 'a'など)を値で返した場合、最初のインスタンスでコンパイラは戻り値に直接構造を作成し、移動コンストラクタもしあれば。 –

0

ですから、パラメータを変更したい場合は...

template <class BIDirContainer> 
inline BIDirContainer& reverse(BIDirContainer& a) 
{ 
    std::reverse(begin(a), end(a)); 
    return a; 
} 

は:

template <class BIDirContainer> 
inline BIDirContainer reverse(BIDirContainer a) 
{ 
    std::reverse(begin(a), end(a)); 
    return a; 
} 

関数の戻り値は、すでに右辺値(あります具体的には「x値」)。移動セマンティクスを持つ関数に渡すと移動されますが、上記の名前付き戻り値最適化(NRVO)resultがインプレースで構築される場合もあります(移動セマンティクスよりも優れています)。

+0

refで渡すときに、なぜそれを返す必要がありますか? – Jagannath

+0

これはrvalue-referencesをどのように説明していますか? – Jagannath

+0

@ Jagannath:最初のバージョンでrefが返されるので、ostreamのような呼び出しを連鎖させることができます。私は詳細を追加しました。 –

関連する問題