假设C盘下文件C:\1.txt,里面存储的是一些int型数据,现在要把这些数据读入一个list中,或许我们就写出了下面的代码:
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<int>,
第一个参数std::istream_iterator<int>(infs),相当于std::istream_iterator<int> infs,即参数名称为infs,类型为std::istream_iterator<int>。
第二个参数std::istream_iterator<int>(),相当于是个函数指针,返回值为std::istream_iterator<int>,没有参数。
如果想让编译器按我们的意愿走,我们依据“用括号包围一个形参是不合法的,但用括号包围一个函数调用时合法的”,做出如下修改:
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