yassin
yassin

Reputation: 6707

Bizarre C++ compiler problem

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;

However, I get the error while compiling:

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 (*)())'

However, if I replace (1) by (2), it compiles.

I'm using g++ 4.4.0

What's wrong?

Upvotes: 3

Views: 455

Answers (2)

The compiler and you are interpreting this line differently:

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

For you it is defining and initializing a variable lineas of type vector<string> with the constructor that takes two iterators.

For the compiler you are defining a function lineas returning a vector<string> and taking two arguments the first of which is an isiand the second of which is a function taking no arguments and returning an isi... With time you will get used to reading compiler errors and what it is reading from your code.

The simplest solution is adding an extra pair of parenthesis:

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

You can find a longer explanation in the C++ FAQ Lite here.

Upvotes: 12

First line according to C++ rules stating that "everything what's possible will be parsed as a declaration will be passed as a declaration" so in your example you are declaring a fnc named lineas which takes first argument::
isi(cin),
of type isi called cin and second argument:
isi() pointer to function not taking any arguments and returning object of type isi. Your function returns vector of strings as a result;

Upvotes: 1

Related Questions