奇怪的C++编译器问题

3

I have the following C++ code:

typedef istream_iterator<string> isi;

// (1)
vector<string> lineas(isi(cin), isi());

// (2)
//vector<string> lineas;
//copy(isi(cin), isi(), back_inserter(lineas));

typedef vector<string>::iterator vci;
for (vci it = lineas.begin(); it != lineas.end(); ++it)
    cout << *it << endl;

然而,编译时我遇到了错误:
test.cpp: In function 'int main(int, char**)':
test.cpp:16: error: request for member 'begin' in 'lineas', which is of non-class type 'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(main(int, char**)::isi, main(int, char**)::isi (*)())'
test.cpp:16: error: request for member 'end' in 'lineas', which is of non-class type 'std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(main(int, char**)::isi, main(int, char**)::isi (*)())'

然而,如果我用(2)替换(1),它就可以编译。

我正在使用g++ 4.4.0。

出了什么问题?


1
请勿尝试使用HTML标签格式化代码 - 使用文本输入区域上方的1010按钮。 - anon
2个回答

12

编译器和你对这行代码的解释不同:

vector<string> lineas( isi(cin), isi() );

对于你来说,这是定义和初始化一个变量lineas,类型为vector<string>,并使用接受两个迭代器的构造函数。

对于编译器而言,你正在定义一个返回vector<string>并带有两个参数的函数lineas。其中第一个参数是isi,第二个参数是一个不带参数并返回isi的函数……随着时间的推移,你会习惯阅读编译器错误以及它从你的代码中读取的内容。

最简单的解决方案是添加一个额外的括号:

vector<string> lineas( (isi(cin)), isi() );

你可以在C++ FAQ Lite 这里找到更详细的解释。


2
“其中第一个是函数本身...” <- 你的意思是“第二个” :) 第一个是接受“isi”。 - Johannes Schaub - litb
没错...已经纠正了。我倾向于懒得读错误消息。一旦我知道问题和解决方案是什么,我就倾向于关闭神经元 :) - David Rodríguez - dribeas
我认为 isi(cin>>skipws()) 同样有效 - 或者如果你真的想要的话,可以使用 isi(cin>>noskipws()) - MSalters

1

根据C++规则的第一行,声明将被解析为声明的所有可能性都将被解析为声明,因此在您的示例中,您正在声明一个名为lineas的fnc,它需要第一个参数:
isi(cin),
类型为isi的cin和第二个参数:
isi() 指向不带任何参数并返回isi类型对象的函数的指针。您的函数将返回字符串向量作为结果;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接