Odd behaviour with istream_iterator

J

Juha Nieminen

I'm using gcc 3.3.5. This code:

std::set<std::string> t(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>());

gives a strange error message:

error: cannot use `::' in parameter declaration

If I try it this way:

std::istream_iterator<std::string> is(std::cin);
std::istream_iterator<std::string> eof();
std::set<std::string> t(is, eof);

it also gives an error:

error: no matching function for call to `std::set<*snip*>::set(*snip*)'

Strangely enough, this:

std::set<std::string> t((std::istream_iterator<std::string>(std::cin)),
std::istream_iterator<std::string>());

compiles and works just fine. The only difference is the extra
parentheses around the first parameter. I can't get the second version
above to compile regardless of any amount of parentheses anywhere.

Even more strangely, if I add the extra parentheses around the
second parameter, like this:

std::set<std::string> t((std::istream_iterator<std::string>(std::cin)),
(std::istream_iterator<std::string>()));

it once again doesn't compile:

error: syntax error before `)' token

I don't understand this. What's going on?
 
E

edd

I'm using gcc 3.3.5. This code:

std::set<std::string> t(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>());

gives a strange error message:

error: cannot use `::' in parameter declaration

If I try it this way:

std::istream_iterator<std::string> is(std::cin);
std::istream_iterator<std::string> eof();
std::set<std::string> t(is, eof);

it also gives an error:

error: no matching function for call to `std::set<*snip*>::set(*snip*)'

I believe it's a bug in gcc 3.3. It thinks you're declaring a function
called 't'. Similarly for your second error, it thinks a function
called 'is' is being declared.
http://www.gnu.org/software/gcc/bugs.html#known (Parse errors for
"simple" code)

gcc 3.4 and onwards should cope fine.

Here is another possible work around (don't have 3.3 on this machine
to test the theory):

typedef std::istream_iterator<std::string> iter_t;
iter_t is = iter_t(std::cin);
iter_t eof;
std::set<std::string> t(is, eof);

Kind regards,

Edd
 
A

antonov84

I'm using gcc 3.3.5. This code:

std::set<std::string> t(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>());

gives a strange error message:

error: cannot use `::' in parameter declaration

Compiler tries to look on your line as on a function declaration
(function t, which receives istream_iterator with improper param name
std::cin (cant use qualified names in function param declaration), and
a pointer to function which receives nothing, returns
istream_iterator(unnamed second parameter of t). Finally, function t
returns a set).
If I try it this way:

std::istream_iterator<std::string> is(std::cin);
std::istream_iterator<std::string> eof();
std::set<std::string> t(is, eof);


here you have another function delcaration - eof (receives nothing,
returns istream_iterator), thats why you cant toss it to t's
constructor second param.

Remember: function declarations can be local, and they're given
priority when deciding what the line of code means.
std::set<std::string> t((std::istream_iterator<std::string>(std::cin)),
std::istream_iterator<std::string>());

because you cant use parentheses around a param in a function
declaration, this is correctly interpreted as a set constructor call.

Dont know about the last lines you posted. They compile fine on VS
2005 compiler.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top