C++の怒りの解析を警戒する

1872 ワード

Cディスクの下のファイルC:1を仮定します.txt、int型のデータが格納されています.リストに読み込むと、次のコードが書かれているかもしれません.
         std::ifstream infs("c:\1.txt");
         std::list<int>listInt(std::istream_iterator<int>(infs),std::istream_iterator<int>());

しかし、これは予想通りではなく、listIntオブジェクトも作成されていません.
 
原因を分析する
戻り値voidを宣言し、パラメータタイプintの関数には次の方法があります.
         void f(int i);
         void f(int(i));
         void f(int);

戻り値がvoidで、パラメータが関数ポインタ(指す関数がvoidを返し、パラメータがない)であることを宣言する方法は、次のとおりです.
         void f(void (*pf)());
         void f(void pf());
         void f(void ());

振り返って分析します.
std::list<int>listInt(std::istream_iterator<int>(infs),std::istream_iterator<int>());

関数listIntが宣言され、std::list
最初のパラメータstd::istream_iterator(infs)、std::istream_に相当iteratorinfs、すなわちパラメータ名infs、タイプstd::istream_iterator.
2番目のパラメータstd::istream_iterator()、関数ポインタに相当し、戻り値はstd::istream_iterator、パラメータはありません.
 
コンパイラを私たちの意思通りに行かせるには、「形パラメータをカッコで囲むのは合法的ではありませんが、関数呼び出しをカッコで囲むのは合法的です」に基づいて、次のように変更します.
std::list<int> li((std::istream_iterator<int>(inf)),std::istream_iterator<int>());

あるいは正直にこう書きます.
         std::ifstream infs("ints.dat");
         std::istream_iterator<int> dataBegin(infs);
         std::istream_iterator<int> dataEnd;
         std::list<int>data(dataBegin, dataEnd);

 
これは、スタックにデフォルトのコンストラクション関数を持つクラスのオブジェクトを定義するときに、なぜカッコを付けないのかを説明します.
class Test{};
Test t(); //  ,        t,     Test      
Test t;         //  ,    t