八叶一刀·无仞剑

万物流转,无中生有,有归于无

导航

由于C++编译器的分析机制所导致的声明问题

Posted on 2016-10-04 10:21  闪之剑圣  阅读(263)  评论(0编辑  收藏  举报

假设我们想声明一个STL的vector类型的变量,读入文件里的信息:

std::ifstream in("data.txt");
std::vector<int> data(std::istream_iterator<int>(in),std::istream_iterator<int>());

之后我们引用data的元素时,会发现编译器报错。为什么呢,让我们来分析一下:

在此时的编译器看来,我们实际上声明的是一个函数,它的返回值是vector,参数有两个,第一个参数为一个istream_iterator对象,第二个参数为一个无参数的,返回istream_iterator的函数指针

造成这种现象是因为C++的编译机制会尽量将语句解释为函数声明。

这种现象实际上并不稀奇,比如如下一段代码你或许也见过:

class Widget
{...};    //内部有一个默认构造函数
Widget w();//此时编译器会将w看做一个函数声明    

解决这种问题的一个方法是给第一个参数加一个括号:

std::vector<int> data((std::istream_iterator<int>(in)),std::istream_iterator<int>());

C++不允许给函数的形参加括号,但允许给函数的实参加括号。这样一来编译器就确认data是一个vector对象了。

当然,治本的方法还是使用临时变量:

std::ifstream in("data.txt");
std::istream_iterator dataBegin(in);
std::istream_iterator dataEnd;
std::vector<int> data(dataBegin,dataEnd);

此博客内容参考《Effective STL》第6条。