警惕C++令人恼怒的解析


假设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


 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值