Effective stl 第6条

来源:互联网 发布:方舟史上最强优化 编辑:程序博客网 时间:2024/05/06 15:22

第6条 当心C++编译器最烦人的分析机制

当将一个存有整数(int)的文件复制到一个list中时,假设采用:

ifstream dataFile("ints.dat");

list<int> data(istream_iterator<int>(dataFile),  istream_iterator<int>());

即将一对istream_iterator传入list的区间构造函数中。 这段代码可能会通过编译,但是不会实现效果

因为分析成了一个函数。。。。接着往下看


首先看三个函数声明一

1、int   f(double)

2、int  f(double (d))      //d两边的括号被忽略

3、int  f(double)      //参数名被忽略

原来可以给参数名加上圆括号.........


再看三个函数声明二:

声明了一个函数g,参数是一个指向不带任何参数的函数的指针,这个函数返回double

1、int  g( double (*pf) () )

2、int   g(double  pf() )     //pf为隐式指针

3、int   g(double()).         //省去参数名


围绕参数名的括号,一(2)中,与独立括号,二(3)的区别:

围绕参数名的括号被忽略,独立的括号则表明参数列表存在:它们说明存在一个函数指针


之后再分析最开头的问题:

list<int> data(istream_iterator<int>(dataFile),  istream_iterator<int>());

被分析为声明了一个函数data,返回值是list<int> ,这个data有两个参数:

第一个是dataFile, 类型是istream_iterator<int>,   dataFile两边的括号是多余的,会被忽略

第二个参数没有名称,类型是指向不太参数的函数的指针,该指针返回一个 istream_iterator<int>。。。。。

好纠结。。竟然分析成这样,这是c++编译器的分析机制导致的:尽可能的解释为函数声明。


一个解决方法是:(istream_iterator<int>(dataFile)加上括号

list<int> data ( (istream_iterator<int>(dataFile)),  istream_iterator<int>());

但是并不是所有编译器都接受


更好的方式是在对data的声明中避免使用匿名的istream_iterator对象,如下:

ifstream dataFile("ints.dat");

istream_iterator<int>  dataBegin(dataFile);

istream_iterator<int>  dataEnd;

list<int>  data(dataBegin, dataEnd);


使用命名的迭代器对象与通常的STL程序风格相违背,但是为了使所有的编译器都没有二义性,并未好维护,这个代价是值得的




 

0 0
原创粉丝点击