12.6.1-明示的な初期化
struct complex {
complex();
complex(double);
complex(double,double);
};
complex sqrt(complex,complex);
complex g = { 1, 2 }; // construct complex(1, 2)
// using complex(double, double)
// and *copy/move* it into g
8.5イニシャライザー
14-フォームで発生する初期化
T x = a;
引数の受け渡し、関数の戻り、例外のスロー(15.1)、例外の処理(15.3)、および集約メンバーの初期化(8.5.1)は、コピー初期化と呼ばれます。[注:コピー初期化により、移動(12.8)が呼び出される場合があります。—エンドノート]
15-フォームで発生する初期化
T x(a);
T x{a};
また、新しい式(5.3.4)、static_cast式(5.2.9)、関数表記型変換(5.2.3)、およびベースとメンバーの初期化子(12.6.2)は、直接初期化と呼ばれます。
8.5.4リストの初期化[dcl.init.list]
1-リスト初期化は、braced-init-listからのオブジェクトまたは参照の初期化です。このような初期化子は初期化子リストと呼ばれ、リストのコンマ区切りの初期化子句は初期化子リストの要素と呼ばれます。初期化子リストが空の場合があります。リストの初期化は、直接初期化またはコピー初期化のコンテキストで発生する可能性があります。直接初期化コンテキストでのリスト 初期化は直接リスト初期化と呼ばれ、コピー初期化コンテキストでのリスト初期化はコピーリスト初期化と呼ばれます。
アトミックの問題
29.6.5アトミックタイプの操作の要件[atomics.types.operations.req]
#define ATOMIC_VAR_INIT(value)
下記参照マクロは、値と初期化互換性のあるタイプの静的ストレージ期間のアトミック変数の定数初期化に適したトークンシーケンスに展開されます。[注:この操作では、ロックを初期化する必要がある場合があります。— end note]初期化される変数への同時アクセスは、アトミック操作を介しても、データ競合を構成します。[ 例:
atomic<int> v = ATOMIC_VAR_INIT(5);
前のセクションによると、§12.8.31と§12.8.32に従って省略されたとしても、コピーコンストラクタが関与しない代入の初期化はあってはならないようですが、アトミックは次のように定義されています。
29.5原子タイプ[atomics.types.generic]
atomic() noexcept = default;
constexpr atomic(T) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T operator=(T) volatile noexcept;
T operator=(T) noexcept;
コピーコンストラクターはありません!
多くの場合、中ATOMIC_VAR_INIT
括弧の初期化のために中括弧の式に展開されますが、atomic<int> v = {5}
それでも代入の初期化であり、一時的なものを直接作成した後のコピーの作成を意味します。
「定数初期化」セクションを調べて、コピーなしでこれを可能にする抜け穴があるかどうかを確認しました(「マクロは、あるタイプの静的ストレージ期間のアトミック変数の定数初期化に適したトークンシーケンスに展開されるため」初期化-値と互換性があります」)が、私はすでにあきらめています。
関連する議論:
http://thread.gmane.org/gmane.comp.lib.qt.devel/8298
http://llvm.org/bugs/show_bug.cgi?id=14486
編集
控除プロセスを構築しながら、関連する標準セクションを引用する回答が理想的です。
結論
したがって、Nicol Bolasによる良い答えの後、面白い結論はcomplex g = { 1, 2 }
、標準が示唆しているコピー(コピーリスト初期化は直接リスト初期化のように解決される)ではないコピー(コピー初期化コンテキスト)であるということです。コピー操作があります(12.6.1:) ...and copy/move it into g
。