06項 C++で最も奇妙な解析に注意しよう

C++で最も奇妙な解析に注意しよう



listのオブジェクトdataを作成するために範囲コンストラクタを呼びだそうとして、下のコードを書いたとします。

ifstream datafile("ints.dat");
list<int> data(istream_iterator<int>(datafile), istream_iterator<int>());

このコードはオブジェクトを宣言できておらず、関数を宣言したことになっています。
戻り値list<int>、第一引数はistream_iterator<int>、第二引数はパラメータを取らずistream_iterator<int>を返す関数へのポインタを受け取る関数になります。


オブジェクトを作成するには、第一引数を括弧で囲みます。

ifstream datafile("ints.dat");
list<int> data((istream_iterator<int>(datafile)), istream_iterator<int>());

二重の括弧をもつ関数宣言"void func(());"が不正となるように、dataは関数宣言と認められなくなるので、dataはオブジェクトと認識されます。

もしくは、イテレータを事前に宣言します。こちらのほうがわかりやすいです。

ifstream datafile("ints.dat");
istream_iterator<int> databegin(datafile);
istream_iterator<int> dataEnd;
list<int> data(databegin, dataEnd);

この項のまとめには、Oracleこちらのページも参考にしました。