2016-08-24 9 views
3

詳細な説明が必要とされている 共有ポインタ

auto sp = std::make_shared<Foo>(); 

auto sp(std::make_shared<Foo>()); 

の違いは何であるの構築の違い。

答えて

5

この特定のケースでは、ゼロ差があります。 2つの宣言は完全に同等です。


TUは型であると仮定)もう少しコンテキストを追加します。

最も一般的な場合は、このている:この場合

U makeU(); 

T direct(makeU()); 
T copy = makeU(); 

、最初の行は、直接的な初期化です。Tには、Uなどを受け入れるコンストラクタが必要です。Uが暗黙的に変換できるものがあります。

2行目は、コピーの初期化でです。コンパイラは概念的にはこれを意味するように書き換える:一時T一時Tcopyに移動(またはコピー)されていることを、次いでUオブジェクトから初期化され、さ

T copy(T(makeU())) 

。つまり、Tにはdirectと同じコンストラクタと、アクセスできない非明示的なコピーまたは移動コンストラクタが必要です。

この場合
T makeT(); 

T direct(makeT()); 
T copy = makeT(); 

、これら二つはほぼ同等である。

Aわずかにより特殊ケースは、UTであるときに起こります。両方とも、コピー/移動コンストラクタを使用して、によって返されたTの一時的なものからTと宣言されたものを初期化します。唯一の違いは、そのコピー/移動コンストラクタがexplicitと宣言されていてもdirectが機能しますが、copyはそのような場合にエラーになります。

変数宣言でTautoに置き換えると、元のケースが得られます。 std::shared_ptrのコピーおよび移動コンストラクタにはexplicitと表示されていないため、2行は完全に同等です。

+0

それはゼロ差ではありません。 1番目はコンストラクタのみを呼び出します。 2番目のコールコンストラクタ、およびプラス(非明示的なコピーまたは移動コンストラクタ)プラスはゼロではありません。 – pepero

+0

@pepero 'T = U'のとき、純差**は**ゼロです。これは、コピー/移動ctorを2度呼び出すことはありません。 – Angew

3

std::shared_ptr<T>にはアクセス可能な非明示的なコピーコンストラクタがありますので、それほど相違はありません。

アセンブリコードを生成すると、両方の例でコンパイラが同じアセンブリを生成することがわかります。

例#1(コピー初期化):

auto sp = std::make_shared<Foo>(); 

Assembly Code

例#2(直接初期化):

auto sp(std::make_shared<Foo>()); 

Assembly Code

関連する問題