3

重複の叫びが始まる前に: 次の質問 (およびその他の質問) がこの質問に非常に関連していることを認識しています。

コピー初期化と直接初期化の間に C++ の違いはありますか?

この質問の回答は、コピーの初期化が不可能なシナリオを完全に説明し、2 つの違いとそのすべてを説明しています。ただし、私の質問はより微妙です。

次のコードを検討してください。

A createA(){...}

A a1 = createA();
A a2(createA());

A は暗黙的にコピー構築できると仮定すると、 と の両方の初期化は問題a1ありませんa2。のコピー コンストラクターには副作用がないAため、両方の初期化も意味的に同等です。createA()最初にキャストする必要があるものではなく、変数の型を直接返します。このケースはかなり多いと思います。

したがって、この場合、両方の選択肢が等しく適用可能であり、意味的に同等である場合、どちらを使用する必要がありますか? 仕様またはコミュニティのコンセンサス/ベストプラクティスに推奨事項はありますか?それとも、どちらを使用するかは私と私のコーディングスタイル次第ですか? C++11 は、古い標準と比較して何か違いを導入しましたか?

4

2 に答える 2

2

他のすべて (セマンティクス、パフォーマンスなど) が等しい場合、それは明らかに好みやスタイルの慣習の問題にすぎません。しかし、最近では多くの著者が直接初期化のためのリスト初期化子を提唱しています:

A a3 {createA()};

しかし、2 つ (3 つ) の選択肢のうちの 1 つを決定するのは、あなた (それがあなたの楽しいプロジェクトである場合) または同僚次第だと思います。両方を同じ意味で使用することはお勧めしません。なぜなら、直接初期化とコピー初期化を使用する理由を読者が不思議に思うからです。

于 2013-02-25T12:48:14.913 に答える
1

「常により良い」答えはありません。それはスタイルの問題です。

オブジェクトの型 ( など) の単純な式からオブジェクトを初期化するとき、おそらく代入createA()の形式に精通しているという理由だけで、copy-init をよく使用します。=それ以外の場合、初期化子が異なる型であるか、オブジェクトに複数の初期化子がある場合 (複数のコンストラクター引数、または集約初期化など)、C++ 11 リスト初期化 (別名、統一初期化構文) を使用することを好みます。より多くの場所、たとえば、ユーザー定義のコンストラクターを持つクラスと同様に集約を初期化し、関数宣言として解析することはできません:

A a1{ createA() };

上記の形式の list-init は direct-init を使用しますが、この形式は copy-init を使用します。

A a2 = { createA() };

=list-init を使用する場合、冗長な記号のない direct-init 形式を好みます。

list-init が不可能な場合がいくつかあります。たとえば、型に initializer-list コンストラクター (つまり、 の特殊化であるパラメーターを取るものstd::initializer_list) があり、別のコンストラクターを呼び出したいが、initializer-list がコンストラクターが選択されます。たとえばstd::vector<int> v{ 5u, 0 };、値がゼロの 5 つの要素のベクトルを作成するのではなく、値が 5 とゼロの 2 つの要素を含むベクトルを作成します。

于 2013-02-25T12:49:11.020 に答える