奇怪的C ++编译问题

时间:2010-04-16 10:46:39

标签: c++

我有以下C ++代码:

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

怎么了?

2 个答案:

答案 0 :(得分:12)

编译器和您正在以不同方式解释此行:

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

对于你来说,它是使用带有两个迭代器的构造函数定义和初始化类型为lineas的变量vector<string>

对于编译器,您要定义一个函数lineas,返回一个vector<string>并取两个参数,第一个参数是isi,第二个参数是一个不带参数的函数返回isi ...随着时间的推移,您将习惯于阅读编译器错误及其从代码中读取的内容。

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

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

您可以在C ++ FAQ Lite here中找到更长的解释。

答案 1 :(得分:1)

根据C ++规则的第一行声明“将所有可能将被解析为声明的内容将作为声明传递”,因此在您的示例中,您声明了一个名为lineas的fnc,它接受第一个参数::
ISI(CIN),
类型isi称为cin和第二个参数:
ISI() 指向函数的指针不带任何参数并返回isi类型的对象。您的函数返回字符串向量作为结果;