目標:オブジェクトをリスト初期化できるようにし、デフォルトの初期化ですべてのPODを0/に初期化false
し、定型文をできるだけ少なくする(C ++ 11)。
いくつかのPODを持ついくつかのクラスがあると仮定します(ファイル形式の解析を考えてください)。未定義の値を処理しないために、デフォルトの構築オブジェクトを0に値初期化する必要があります。たとえば、すべてのメンバーに明示的に名前を付ける場合と同様に、このような場合に正常に機能する独自のデフォルトmemset()
のC'torを提供します。this
ただし、これは定型文です。さらに重要なことに、引数のない独自のデフォルトコンストラクターを提供すると、メンバーの初期化にリスト初期化構文を使用できなくなります。
class Fails1 {
public:
int a, b;
Fails1() { memset(this, 0, sizeof(*this)); }
};
Fails1 this_works;
Fails1 this_fails{ 42, 54 }; // compiler error
のコンストラクターを追加することもできinitializer_list
ますが、それはさらに定型的なものです。ボイラープレートをすべて避けたい。
そこで、ユーザーが提供するデフォルトコンストラクターがない場合に、コンパイラーによって提供されるデフォルトコンストラクターを、さまざまなメソッドと組み合わせて初期化する方法を調べました。これが私が完全に混乱したところです:
class A {
public:
int a, b;
};
このクラスを使用すると、両方のコンストラクターを自分で提供しなくても、空の初期化リストと値を持つリストの両方を使用できます。それは私が欲しいものの一部です。
// Example 1: default initialization
A a1;
最初の例では初期化を使用しています。メンバーa
であり、b
後で未定義になります(私が望むものではなく、値を初期化する必要があります)。
// Example 2: Value-initialization, so this works, I guess:
A a2 = A();
例2は値の初期化を使用し、後でコピーしません。それが私が望んでいることですが、空のbrace-init-listsでも同じことができると思いました。次の例を参照してください。
// Example 3: list-initialization with empty brace-init-list
A a3{};
例3は、私がそのトリックを実行すると思ったものです。空のbrace-init-listを使用したリストの初期化については、8.5.4「リストの初期化」で説明しています。特に8.5.4.3は、「初期化子リストに要素がなく、Tがデフォルトのコンストラクターを持つクラス型である場合、objectvalue-initialized」と述べています。ただし、これにより、g++4.7.2で次の警告が発生します-Wextra
。
missing initializer for member ‘A::a’ [-Wmissing-field-initializers]
missing initializer for member ‘A::b’ [-Wmissing-field-initializers]
ただし、clang ++ 3.1による警告はないため、g++のバグである可能性もあります。
では、元の質問に戻りましょう。initializer_list
独自のボイラープラットフォームのデフォルトコンストラクターを提供せずにオブジェクトを値初期化するにはどうすればよいですか?独自のコンストラクターを提供せずにメンバーのリスト初期化を使用する機能を維持しながら?