初期化子リスト

C++11では初期化子リスト(initializer_list)というのがあって,配列を初期化するのに使う.
例えば,

#include <iostream>
#include <algorithm>
#include <vector>
int main(){
	std::vector<int> a={1,2,3};
	std::for_each(a.begin(),a.end(),[](int x){std::cout << x << std::endl;});
	return 0;
}

という形で,std::vectorなどを初期化することができる.
この{1,2,3}の部分の型は,カッコ内の変数の型によって型が決まる.
この場合int型になるだろう.(全体は std::initializer_list という型.)
これを上記のように std::vector 型の変数で受ければ,問題なく変数aが初期化される.

	std::vector<double> b={1,2,3};

の場合,右辺は本来int型だが,bの型がdoubleなので,double型のvectorになる.
しかし,次のように一旦autoの変数で受けてしまうと,この場合は {1,2,3} の中の型で変数の型が決定されてしまい,bbはstd::vectorになる.

	auto bb={1,2,3};
	std::vector<double> b=bb;

なので,上記のコードはstd::vectorとstd::vectorの代入が出来ないのでコンパイルエラーになる…のかな?
一方で,違う型を指定したらどうなるか調べてみた.

	std::vector<int> c={1.f, 2.f, 3.f};

この場合,右辺はfloat型に対して左辺はint型.
これでコンパイルをすると,

test2.cpp: In function 'int main()':
test2.cpp:11:30: warning: narrowing conversion of '1.0e+0f' from 'double' to 'int' inside { } [-Wnarrowing]
  std::vector<int> f={1.f,2.f,3.f};

という感じで,精度が落ちる変換が行われてることがwarningで出た.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です