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);