最終更新日時: 2025年05月12日 18時32分12秒 (JST)
Akira Takahashi が更新

履歴 編集

# 要素数不明の配列を集成体初期化する規則を明確化 [P3106R1](C++26)

このページはC++26に採用される見込みの言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

## 概要

C++26では、集成体の配列を初期化する際に、中カッコ `{}` を省略した場合の動作について、規格内で矛盾があった問題を修正する。

C++23までの仕様として、要素数不明の配列を初期化する際、配列の要素数は初期化子リスト内の初期化子の数で決まると規定されていた。しかしこの仕様では、中カッコ `{}` を省略した場合の動作に矛盾があった：

    struct X { int i, j, k = 42; };

    // 実際の動作としては、どちらの要素数も2になる。
    // C++23仕様ではaは6になるはずだが、実態と合っていない
    X a[] = { 1, 2, 3, 4, 5, 6 };
    X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };

C++26ではこれを、実際のコンパイラの動作に合わせた仕様に修正する。動作としてはおそらく変わることはないと考えられる。

そのほかの例：

    struct S1 { int a, b; };
    struct S2 { S1 s, t; };

    // xとyは同じ値
    S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    S2 y[2] = {
      {
        { 1, 2 },
        { 3, 4 }
      },
      {
        { 5, 6 },
        { 7, 8 }
      }
    };

    // y[3]要素の初期化子は省略されている
    float y[4][3] = {
      { 1, 3, 5 },
      { 2, 4, 6 },
      { 3, 5, 7 },
    };

    // この初期化子は上記と同じ効果を持つ
    float y[4][3] = {
      1, 3, 5, 2, 4, 6, 3, 5, 7
    };

    struct S { } s;
    struct A {
      S s1;
      int i1;
      S s2;
      int i2;
      S s3;
      int i3;
    } a = {
      { },  // s1の初期化子
      0,
      s,    // s2の初期化子
      0
    };      // s3とi3は未初期化

    struct A {
      int i;
      operator int();
    };
    struct B {
      A a1, a2;
      int z;
    };

    A a;
    B b = { 4, a, a };
    // b.a1.iは4で初期化
    // b.a2はaで初期化
    // b.zはaのint変換演算子の結果で初期化

## 参照

- P3106R1 Clarifying rules for brace elision in aggregate initialization