これT v(x);
は直接初期化とT v = x;
呼ばれ、コピー初期化と呼ばれます。これは、コピー/移動されるT
一時的なものを構築することを意味します(これはおそらく省略されます)。x
v
リストの初期化では、標準はコンテキストに応じて2つの形式を区別します。直接リスト初期化と呼ばれ、T v{x};
コピーリスト初期化と呼ばれます。T v = {x};
§8.5.4 [dcl.init.list] p1
[...]リストの初期化は、直接初期化またはコピー初期化のコンテキストで発生する可能性があります。直接初期化コンテキストでのリスト初期化は直接リスト初期化と呼ばれ、コピー初期化コンテキストでのリスト初期化はコピーリスト初期化と呼ばれます。[...]
ただし、標準全体でそれぞれ2つだけ参照があります。T{x}
直接リスト初期化の場合、 ( )のような一時的なものを作成するときに言及され§5.2.3/3
ます。copy-list-initializationの場合、return {x};
(§6.6.3/2
)のようなreturnステートメントの式用です。
では、次のスニペットはどうですか?
#include <initializer_list>
struct X{
X(X const&) = delete; // no copy
X(X&&) = delete; // no move
X(std::initializer_list<int>){} // only list-init from 'int's
};
int main(){
X x = {42};
}
通常、パターンから、のmoveコンストラクターはdとして定義されているX x = expr;
ため、コードのコンパイルに失敗すると予想されます。ただし、最新バージョンのClangとGCCは上記のコードを問題なくコンパイルし、少し掘り下げて(そして上記の引用を見つけて)、それは正しい動作のようです。この標準は、リストの初期化全体の動作を定義するだけであり、上記の点を除いて、2つの形式をまったく区別しません。まあ、とにかく、少なくとも私が見る限りでは。X
delete
だから、私の質問をもう一度要約すると:
リストの初期化を(明らかに)まったく同じことを行う場合、2つの形式に分割することの使用は何ですか?