Unfortunately, this is a function declaration:
vector<int> vec(istream_iterator<int>(cin), istream_iterator<int>());
It's a function named vec
, that returns a vector<int>
by value and takes two parameters: an istream_iterator<int>
with a formal parameter name of cin
, and a function with no formal parameter name that returns an istream_iterator<int>
, and takes no parameters.
Why?
Basically, in C++(and C), if a piece of code can be interpreted as a declaration, it will be.
According to N3936::6.8.1 [stmt.ambig]:
There is an ambiguity in the grammar involving expression-statements
and declarations: An expressionstatement with a function-style
explicit type conversion (5.2.3) as its leftmost subexpression can be
indistinguishable from a declaration where the first declarator starts
with a (. In those cases the statement is a declaration. [ Note: To
disambiguate, the whole statement might have to be examined to
determine if it is an expression-statement or a declaration. This
disambiguates many examples. [ Example: assuming T is a
simple-type-specifier (7.1.6),
T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5) << c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; //declaration
T(*g)(double(3)); // declaration
In the last example
above, g, which is a pointer to T, is initialized to double(3). This
is of course ill-formed for semantic reasons, but that does not affect
the syntactic analysis. —end example ]
How to fix it
All we need is something that makes it impossible for the compiler to treat the code as a function declaration.
Adding the extra parentheses around the parameters makes it clear to the
compiler that what we intend to be constructor parameter names can't be parameter declarations.
vector<int> vec((istream_iterator<int>(cin)), istream_iterator<int>());
As your solution showed, using named variables as constructor parameters.