2017-04-05 2 views
5

std::unique_ptrを、std::unique_ptrが所有するデータの所有権を取得するクラスのコンストラクタに渡したいとします。所有者を取得するためにstd :: unique_ptrをコンストラクタに渡す

以下のアプローチfoobarとの間に、コンパイラがそれらを処理する方法の点で違いがありますか?

fooクラス:

template <class T> 
class foo 
{ 
    std::unique_ptr<T> data_; 

public: 
    foo(std::unique_ptr<T>&& data) : 
     data_{ std::forward<std::unique_ptr<T>>(data) } 
    { 
    } 
}; 

barクラス:

基準への結合
template <class T> 
class bar 
{ 
    std::unique_ptr<T> data_; 

public: 
    bar(std::unique_ptr<T> data) : 
     data_{ std::move(data) } 
    { 
    } 
}; 
+0

もう1つは機能しますか? – 101010

+0

あなたのチームが後者によってあまり混乱しないようにして、それを説明する時間を無駄にするのではなく、後者を使用してください。 –

+0

@KerrekSBはOPのチームに混乱して時間を無駄にしたのですか? – Slava

答えて

5

一の少ない動きを必要とする:オブジェクトパラメータにバインド

void f(std::unique_ptr<T>&& p) { g(std::move(p)); } 

f(std::make_unique<T>()); // no move, g binds directly to the temporary 

一の実際の動きを必要とします。

void f(std::unique_ptr<T> p) { g(std::move(p)); } 

f(std::make_unique<T>()); // p constructed (= moved) from temporary, 
          // g binds to p 

余分な移動には、1つのポインタコピー、1つのNULLへのポインタの設定、および条件チェックを伴う1つのデストラクタが含まれます。これは大きなコストではなく、どのスタイルを使用するかは、作成しているコードの種類によって異なります。

コードが葉が多いほど、使用される量が少ないほど、値渡しは簡単です。逆に、コードのライブラリが多ければ多いほど、ユーザーを知る人が少なくなればなるほど、たとえ小さなものであっても、回避可能なコストを課さないという価値があります。

あなたが決定します。

+0

C++ 17では、その余分な動きは正しく行われないことが保証されますか? – NathanOliver

+2

@ NathanOliver:いいえ、それはそれとは関係ありません。だからこそ、私は、「保証コピー・エリシジョン」という言葉を嫌います。 –

+0

@ NathanOliver:基本的に、すべての空白の「XはすべてのYを解決します」という主張を拒否する必要がありますが、それらはすべてナンセンスです。 –

関連する問題