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