《Effective stl》——条款6的笔记

作者Scott Meyers在《Effective STL》书里以条款的方式继续他的C++科普事业。在第六条款,一开始就抛出一个看似很正常的语句
            

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

本意是通过输入流从ins.dat文件读取一系列整数并存到list<int>中,编译可以通过,但是运行期什么也不发生。Meyers通过枚举函数参数


声明的方式一步步揭开编译器之所以会错误解析。
假设我们要声明一个函数,他的功能是返回int 传入参数是 double类型值,一般是这样做的:
int foo(double d);

其实,在声明对象的时候,比如 int a=3;int b=a;可以写作int b=int(a);或者int b=(int)a;
同样的,编译器允许我们参数声明的时候加上括号
int foo(double (d)); //编译器自动去除括号。

更近一步地,可以去除变量名,
int foo(double);

以上三种函数声明,一般的程序员应该都知道。
下面这三种函数声明方式可就有点复杂了。
假设我要声明一个函数foo ,其返回值为int,入参是一个函数指针pf,pf的返回值为double 无入参。
我们可以这么声明。
typedef double (*PF)();
int foo(PF pf ); //比较常见的声明方式。
//等价于
int foo(double (*pf)()); // 只是没用别名

也可以使用非指针语法形式声明pf
int foo(double pf() );

这样以来,pf参数就可以省略了。变成
int foo(double()); // 如果是int foo(double)就是传一个变量,加上"()"就是指针了.看出区别了吗?

看出来了吗,data变量现在被编译器解析成函数声明啦!!!

这行代码声明了一个函数data,它的返回类型是list<int>。这个函数data带有两个参数:
●      第一个参数叫做dataFile。它的类型是istream_iterator<int>。dataFile左右的括号是多余的而且被忽略。
●      第二个参数没有名字。它的类型是指向一个没有参数而且返回istream_iterator<int>的函数的指针。


我用vs2012编译会有警告,说这个是未调用原型函数。
下面如果继续使用data就会报错了,说是未定义变量。
那要怎么能让他编译通过呢,给每个参数加个大括号,表明这个是一个值。

源代码如下:


#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
using namespace std;

int main ( int, char** )
{
	ifstream datafile("E:\\CPPDemo\\ins.txt");
	vector<double> data( (istream_iterator<double>(datafile)),(istream_iterator<double>()));

	for each ( auto elem in data )
	{
		cout<<elem<<endl;
	}

	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值