web-dev-qa-db-ja.com

std :: arrayのデフォルトの初期化?

C++ 11 std::arrayでは、構文std::array<T, N> x;が配列のすべての要素をデフォルトで初期化するという保証がありますか?

EDIT:そうでない場合は、すべての要素をデフォルト値に初期化するためにすべての配列(サイズがゼロの配列を含む)で機能する構文があります?

EDITcppreference で、デフォルトのコンストラクターの説明は次のようになります:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

答えはイエスかもしれません。しかし、私は標準または将来の標準に従ってそれを確実にしたいと思います。

85
Vincent

定義上、デフォルトの初期化は、他の初期化が指定されていないときに発生する初期化です。 C++言語は、明示的な初期化子を提供しないanyオブジェクトがデフォルトで初期化されることを保証します(C++ 11§8.5/ 11)。タイプstd::array<T, N>およびT[N]のオブジェクトが含まれます。

デフォルトの初期化が効果を持たず、オブジェクトの値を不確定なままにする型があることに注意してください:任意の非クラス、非配列型(§8.5/ 6)。その結果、そのようなタイプのオブジェクトのデフォルトで初期化された配列は、不定の値を持ちます、例えば:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

Cスタイルの配列とstd::arrayの両方には、plain_intに不定値があるのと同様に、不定値の整数が格納されます。

すべての要素をデフォルト値に初期化するために、すべての配列(サイズがゼロの配列を含む)で機能する構文はありますか?

「デフォルト値に」と言うとき、あなたは本当に「すべての要素をT{}に初期化する」ことを意味すると推測しています。それはデフォルトの初期化ではなく、値の初期化(8.5/7)です。 C++ 11では、各宣言に空の初期化子を指定することにより、値の初期化を非常に簡単に要求できます。

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

これにより、すべての配列要素の値が順番に初期化され、plain_old_int、および両方の種類の配列のすべてのメンバーがゼロに初期化されます。

126
Casey

デフォルトの初期化は、潜在的に初期化をまったく行わない可能性があることを意味する標準の用語であるため、おそらくzero-initializationを意味します。

Cppreference.comの説明は、実際には少し誤解を招くものです。 std::arrayは集合クラスであり、要素タイプがプリミティブである場合、POD:「プレーンデータ」であり、セマンティクスはC言語にほぼ一致します。 std::array< int, N >の暗黙的に定義されたコンストラクタは、trivialであり、絶対に何もしません。

ゼロ化された値を提供するstd::array< int, 3 >()std::array< int, 3 > x{}などの構文は、コンストラクターを呼び出してもそうしません。ゼロを取得することは、C++ 11§8.5/ 8で指定されているvalue-initializationの一部です。

タイプTのオブジェクトを値で初期化するとは、次のことを意味します。

— Tが、ユーザー提供または削除されたデフォルトコンストラクターを持たない(おそらくcv修飾された)クラス型である場合、オブジェクトはゼロで初期化されます…。

std::arrayにはユーザー指定のデフォルトコンストラクターがないため、ゼロで初期化されます。暗黙的に定義されたデフォルトコンストラクターがありますが、簡単なので、デフォルトで初期化されることはありません。 (ただし、定義による些細な初期化は実行時に効果がないため、これは違いを生じません。)

そうでない場合、すべての要素をデフォルト値に初期化するために、すべての配列(サイズがゼロの配列を含む)で機能する構文がありますか?

Cスタイルの配列とstd::arrayはどちらも集合体であり、集合体を完全にゼロで初期化する方法は、= {}という構文を使用することです。これはC++ 98以降で機能します。 Cスタイルの配列はエクステントをゼロにすることはできず、sizeof (std::array< X, 0 >)はゼロではないことに注意してください。

18
Potatoswatter

T x[N];std::array<T, N> x;の両方は、配列のすべての要素をデフォルトで初期化します。

たとえば、T = std::stringの場合、すべての要素は空の文字列になります。 Tがデフォルトコンストラクターのないクラスである場合、両方ともコンパイルに失敗します。 T = intの場合、すべての要素に不定値があります(その宣言が名前空間スコープにある場合を除く)

6
Cubbi

まず、T x [N]はデフォルトで要素を初期化しますが、スカラー型Tのデフォルトの初期化は実際には何もしません。上記はstd :: array xにも当てはまります。必要なのはリストの初期化だと思います。

0
Lingxi