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 asistream_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)
In the newly rebrandished LLVM Try Out (well, it just went from llvm-gcc to clang).
And you get:
And therefore, @john is right,
int(i)
is interpreted asint i
, ie a named parameter to the function.There is a section called
Ambiguity resolution
in the Standard (2003) which is dedicated to such syntaxes. I think I don't need to explain it further if you read the section yourself, for its very clear with lots of examples!So here you go:
Yes, it is the parameter name. And, yes you can add a set of parenthesis, because sometimes you have to.
If the parameter is a function pointer,
void (*f)()
you need to write it like that.The people writing the standard have not spent their precious time pointing out exactly the cases where the parenthesis are allowed or actually required, so the standard just says that you can have them.