記事タイトル部にはてなスターを表示
2026/01/19(月)cpprefjpを読もう。【初期化子リスト】
C++11 初期化子リスト [N2672] cppref
概要
ユーザー定義型オブジェクトに対して、波カッコによるリスト初期化が可能になる機能。
ユーザー定義型 : 標準ライブラリの型を除く、ユーザーによって定義された型
<initializer_list>ヘッダに定義されたstd::initializer_listをパラメータとして、
コンストラクタや代入演算子をオーバーロードする。
つまるところ、任意の型に対してリストのようにイテレータアクセスを可能にしたクラス
(内部実装はコンパイラ側にあって、不明)
貰ったstd::initializer_list<T>のイテレータで良しなに初期化しろっていうことか。
仕様
重要そうなものを抜粋
- 波カッコを使用した初期化子のリストによる、オブジェクトもしくは参照の初期化を
リスト初期化 (list initialization)と呼ぶ。 - 上記の初期化子を
初期化子リスト (initializer list)と呼ぶ。 初期化子リスト (initializer list)は、カンマ区切りで要素を列挙する。初期化子リスト (initializer list)は、空であってもよい。- 使用できる個所は、このクラスを使ってオーバーロードしたコンストラクタや演算子等。
- 初期化子リストに 縮小変換 が要求された場合、プログラムは不適格となる
試しにvectorで見てみる。 wandbox
結果は仕様通り。prog.cc: In function 'int main()': prog.cc:7:49: error: narrowing conversion of '5.0e+0' from 'double' to 'int' [-Wnarrowing] 7 | std::vector<int> container2 {1, 2, 3, 4, 5.0}; | - 以下の条件を満たすコンストラクタを
初期化子リストコンストラクタ(initializer-list constructor)と呼ぶ- 任意の型を要素とする初期化子リストのみを引数とする物。
- 任意の型の初期化子リストおよび、それ以降にデフォルト引数を持つ物。
- オーバーロード解決
デフォルトコンストラクタと初期化子リストコンストラクタがある場合、
空の初期化子リストが渡された場合はデフォルトコンストラクタが呼び出される。
余談
gptを使用してブログのレビューしたんだが、以下のような指摘を受けた。
オーバーロード解決の説明
デフォルトコンストラクタと初期化子リストコンストラクタがある場合、
空の初期化子リストが渡された場合はデフォルトコンストラクタが呼び出される。
⚠ これは誤りです(重要)
正しい仕様
- 初期化子リストコンストラクタが存在する場合
- {} は initializer_list コンストラクタが優先される
- デフォルトコンストラクタが呼ばれるのは:
- initializer_list コンストラクタが存在しない場合
へーそうなんすね、調べてみましょう。
wandbox
コード
#include <iostream>
#include <vector>
#include <initializer_list>
template<class T>
class Test
{
public:
Test()
{
std::cout << "default" << std::endl;
}
Test([[maybe_unused]] std::initializer_list<T> l)
{
std::cout << "initializer_list" << std::endl;
}
};
int main()
{
Test<int> test_default;
Test<int> test_initilizer {1, 2, 3, 4};
Test<int> test_empty {};
}
結果
default
initializer_list
default
嘘じゃねーか!
課金しないとモデル選択できないとは言えさぁ...
ちなみにgemini-3-flashは特に変なことは言っていなかった。
いい加減、AI使うなら課金しないといけないか...