My question is how the following line can be parsed as a function declaration:
vector<int> v(istream_iterator<int>(cin), istream_iterator<int>());
I understand most of the details of the Most Vexing Parse and why the second temporary iterator can be interpreted as a type that is a function returning an iterator and taking no arguments, but what I don't get is why the first temporary iterator can be interpreted as a type.  What type does it represent?  My thought is that it would be some sort of function type, but I can't see how the name cin gets used.  Is it declaring that the parameter is an istream_iterator<int> named cin?  If so, does that mean that you can arbitrarily parenthesize the names of arguments to functions?  And if so, why?
istream_iterator<int>(cin) is exactly the same as istream_iterator<int> cin but with superfluous parens. This declarator syntax was inherited from C, and I think even the inventor of C (Ken Thompson?) described it as a mistake.
Did I already said that I liked Clang (a lot) ?
Just try the following (simplified code)
#include <vector>
void foo(std::vector<int>);
int main() {
  std::vector<int> v(int(i), int());
  foo(v);
}
In the newly rebrandished LLVM Try Out (well, it just went from llvm-gcc to clang).
And you get:
/tmp/webcompile/_21483_0.cc:6:21: warning: parentheses were disambiguated
                                           as a function declarator
  std::vector<int> v(int(i), int());
                    ^~~~~~~~~~~~~~~
/tmp/webcompile/_21483_0.cc:7:3: error: no matching function for call to 'foo'
  foo(v);
  ^~~
/tmp/webcompile/_21483_0.cc:3:6: note: candidate function not viable:
     no known conversion from 'std::vector<int> (int, int (*)())'
     to 'std::vector<int>' for 1st argument
void foo(std::vector<int>);
     ^
3 diagnostics generated.
And therefore, @john is right, int(i) is interpreted as int i, ie a named parameter to the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With