@@ -700,6 +700,58 @@ prog.cc:27:2: warning: ignoring return value of function declared with 'nodiscar
700700```
701701
702702
703+ ### 指示付き初期化子 [ (P0329R4)] ( https://wg21.link/P0329R4 )
704+ C++20 から、集成体において、メンバ変数名を指定した初期化(指示付き初期化子を用いた初期化: "Designated Initialization" )ができるようになります。C 言語 (C99) にも同様の機能がありますが、C++20 では C99 と比較して以下のような制約が追加されています。
705+
706+ - (a) 指示子の順番はメンバの宣言順と同じである必要がある
707+ - (b) 指示付き初期化子と通常の初期化子の混在はできない
708+ - (c) 指示付き初期化は重複できない
709+ - (d) 指示付き初期化のネストはできない
710+ - (e) 配列の指示付き初期化はできない
711+
712+ また、初期化子の評価順序が左から右であることが保証されます。
713+
714+ ``` C++
715+ #include < string>
716+
717+ struct Point
718+ {
719+ int x, y;
720+ };
721+
722+ struct Item
723+ {
724+ std::string name;
725+ int id = -1;
726+ int count = 1;
727+ };
728+
729+ void F (Point) {}
730+
731+ int main()
732+ {
733+ Point p1 = { .x = 10, .y = 20 }; // OK
734+ Point p2{ .x = 10, .y = 20 }; // OK
735+ Point p3 = { .x = 10 }; // OK: y は 0 に初期化される
736+ Point p4 = { .y = 20 }; // OK: x は 0 に初期化される
737+ F({ .x = 10, .y = 20 }); // OK
738+
739+ //Point p4 = { .y = 20, .x = 30 }; // コンパイルエラー: (a) 指示子の順番がメンバの宣言順と異なる
740+ //Point p5 = { .x = 20, 40 }; // コンパイルエラー: (b) 指示付き初期化子と通常の初期化子は混在できない
741+ //Point p6 = { .x = 20, .x = 30, .y = 30 }; // コンパイルエラー: (c) 指示付き初期化子は重複できない
742+
743+ Item i1{ .name = "shield", .id = 30, .count = 100 }; // OK
744+ Item i2{ .id = 0 }; // OK: name は {} で初期化、count は 1 で初期化
745+
746+ //Item i3{ .pos.x = 10, .pos.y = 40 }; // コンパイルエラー: (d) 指示付き初期化のネストはできない
747+
748+ //int arr[3] = {[1] = 5}; // コンパイルエラー: (e) 配列の指示付き初期化はできない
749+ }
750+ ```
751+
752+ 従来までの `Point p{}`, `Item i{}` のような集成体初期化を「指示付き初期化子が 0 個の初期化」と考えると、新しい挙動も理解しやすくなります。
753+
754+
703755## 標準ライブラリ
704756
705757### 文字列の先頭や末尾が、ある文字列と一致するか判定 [(P0457R2)](https://wg21.link/P0457R2)
@@ -1743,3 +1795,45 @@ int main()
174317954
17441796```
17451797
1798+
1799+ ### 組み込み配列から `std::array` を作成する `std::to_array()` [(P0325R4)](https://wg21.link/P0325R4)
1800+ C++17 で導入された型推論ガイドによって、`std::array` で次のようなコードが書けるようになりました。
1801+
1802+ ```C++
1803+ #include <array>
1804+
1805+ int main()
1806+ {
1807+ auto a = std::array{ 1, 2, 3 }; // std::array<int, 3>
1808+ }
1809+ ```
1810+
1811+ しかし、` "hello" ` や ` int[4] ` のような組み込み配列から ` std::array<char, 6> ` や ` std::array<int, 4> ` を作成する方法はありませんでした。
1812+
1813+ ``` C++
1814+ #include < array>
1815+
1816+ int main ()
1817+ {
1818+ auto a1 = std::array{ "hello" }; // std::array<const char*, 1>
1819+
1820+ int xs[4] = { 1,2,3,4 };
1821+ auto a2 = std::array{ xs }; // std::array<int*, 1>
1822+ }
1823+ ```
1824+
1825+ C++20 では、組み込み配列の左辺値または右辺値を引数にとり、値をコピー(ムーブ)して新しい ` std::array ` を作成する補助関数 ` std::to_array() ` が追加され、組み込み配列からの ` std::array ` の作成が簡単になりました。
1826+
1827+ ``` C++
1828+ #include < array>
1829+
1830+ int main ()
1831+ {
1832+ auto a1 = std::to_array("hello"); // std::array<char, 6>
1833+
1834+ int xs[4] = { 1,2,3,4 };
1835+ auto a2 = std::to_array(xs); // std::array<int, 4>
1836+
1837+ auto a3 = std::to_array<long>({ 1, 2 }); // std::array<long, 2>
1838+ }
1839+ ```
0 commit comments