Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A confusing detail about the Most Vexing Parse

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?

like image 788
templatetypedef Avatar asked Aug 10 '11 08:08

templatetypedef


2 Answers

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.

like image 189
john Avatar answered Nov 11 '22 19:11

john


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.

like image 20
Matthieu M. Avatar answered Nov 11 '22 19:11

Matthieu M.