'Is most vexing parse a formally defined concept

I was reading an SO post where one user made the following comment:

Also note that ArrTest<int> ar(); uses most vexing parse.

But another user said the opposite:

ArrTest<int> ar(); is not the "most vexing parse". It's just a function declaration. It's certainly vexing for beginners, but, as the page you linked to indicates, the "most vexing parse" is more convoluted.

The code example from that post is given below for reference:

template <class ItemType>
class ArrTest {
public:
    ArrTest();
private:
    ItemType* info;
};
//some other code here

int main() {
    ArrTest<int> ar();  //DOES THIS USE THE MOST VEXING PARSE?
    return 0;
}

My first question is that is the concept of "most vexing parse" formally defined by the C++ standard. My second question is that does the statement ArrTest<int> ar(); uses most vexing parse. That is, which of the above two quoted comments is technically correct?



Solution 1:[1]

is the concept of "most vexing parse" formally defined by the C++ standard.

No. There is no concept of "most vexing parse" defined in the C++ standard. The standard does define the grammar from which the ambiguities arise, and it defines the rule that resolves the ambiguities, but it doesn't name the ambiguities.

According to Wikipedia: "The term "most vexing parse" was first used by Scott Meyers in his 2001 book Effective STL.". The example in the book is:

Item 6. Be alert for C++'s most vexing parse.

ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), // warning! this doesn't do
               istream_iterator<int>());        // what you think it does

The way I would describe "MVP" is that there is an intention to declare a variable, with passed argument(s), but you end up actually writing a function declaration and the intended arguments turn out as parameter declarators.


does the statement ArrTest ar(); uses most vexing parse.

The book explicitly mentions this ambiguity as well:

If you've been programming in C++ for a while, you've almost certainly encountered another manifestation of this rule. How many times have you seen this mistake?

class Widget {...}; // assume Widget has a default constructor
Widget w();         //'uh oh...

Given that the author who came up with the name for the ambiguity considers this as another manifestation - as opposed to the same manifestation - of a language rule, I would say that the example in question is not the "MVP". It's another, similar, and in my opinion less vexing ambiguity.

Solution 2:[2]

As the author of the second quote in the question, yes, it's a bit pedantic, but applying the term "most vexing parse" to int f();, which every C++ programmer will recognize as a function declaration, is misleading.

When you see int f(); you should thing "function declaration". And when you need to write a declaration of a function that takes no arguments and returns int you should think of int f();. That's how you do it. On the other hand, when you see something like TimeKeeper time_keeper(Timer());, maybe you should think "function declaration", because that's what it is, but if you want to declare a function that takes an argument of type Timer and returns TimeKeeper you should not think of TimeKeeper time_keeper(Timer());. That way lies madness. Or, at best, vexation.

"Most Vexing Parse" is useful as a label that says "you've done something confusing here". int f(); is not confusing; TimeKeeper time_keeper(Timer()); is. On the other hand, if "most vexing parse" is applied to any application of that disambiguation rule, then you need a term for "most vexing parse that's useful and necessary" and another for "most vexing parse that you should not have written". Simpler is better.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Pete Becker