What are the parenthesis in a "most vexing parse" supposed to do?

154 views Asked by At

We all know this is a most vexing parse:

Foo f( Bar() );

Every compiler thinks that's declaring a function. But I've never seen anyone, ever, use parenthesis in a function declaration like that. What do those parenthesis even mean? Supposing it was a function declaration -- are there any differences between

Foo func( Bar() ); //do we need the parenthesis after Bar?
Foo func( Bar );
Foo func( Bar b );

Is "Bar()" equivillent to "Bar" there? Or is there some other behavior that adding the parenthesis means? If not, then why does C++ allow parenthesis in a function declaration like that? It really looks like that ought to be an error in a function delaration, no?

1

There are 1 answers

0
Lightness Races in Orbit On

Is "Bar()" [equivalent] to "Bar" there?

No.

Or is there some other behavior that adding the parenthesis means?

As it would be in any expression, the usual expectation is that this creates a temporary of type Bar. The programmer is hoping to pass that temporary to the function as an argument.

If not, then why does C++ allow parenthesis in a function declaration like that? It really looks like that ought to be an error in a function [declaration], no?

C++ doesn't really have any reason to prohibit this. It's bad enough that the above-described expectation isn't always actually met (because of the most vexing parse); banning the use of temporaries as function arguments altogether would be even worse.

Here's a common and idiomatic example of passing a temporary as a function argument:

// Read all input from cin one word at a time, storing
// the words in col.
std::vector<std::string> col;
std::copy(
   std::istream_iterator<string>(cin),
   std::istream_iterator<string>(),
   std::back_inserter(col)
);

Actually, all of those arguments are temporaries. However, there is only one that (like your example) doesn't itself take any arguments.

Now, if you're asking why C++ could have avoided the most-vexing-parse entirely by banning the other meaning of those parentheses, then, well, it could have done. But… only by substantially altering the structure of the grammar for function declarations, which could have broken existing code relying on antiquated C-isms. Best not, eh?

That the parentheses can mean what the most vexing parse lets them mean, is simply due to the way the grammar is constructed, and a desire not to have "special cases" infecting it everywhere!