Why this is not a vexing parse?
Basically this is a 开发者_Go百科follow up of this question about most vexing parse. I can understand that this is due to the ambiguity between the function declaration and variable definition.
But in Comeau online, I just tired the following.
class T{
public:
T(int i){
}
int fun1(){
return 1;
}
};
int main()
{
T myT(10); // I thought it'd be a function declaration that takes an int and returns a type T
myT.fun1(); // and a compiler error out here.
}
But it compiles fine and there were no errors. I looked into the standard docs but couldn't come to a reasoning.
So, what am I missing here?
Because 10
is not a type. :)
This would be a Most Vexing Parse:
T myT(T());
// T() gets interpreted as function pointer argument to a function returning T();
// This is equivalent to:
T myT(T (*fn)());
Another variety of the Most Vexing Parse is this one:
unsigned char c = 42;
T myT(int(c));
// int(c) gets interpreted as an int argument called c.
// This is equivalent to:
T myT(int c);
The 10
cannot be a parameter type name, so this must be a variable declaration.
The compiler must choose a function declaration when it can do that, but in many cases like this it cannot and there is no ambiguity.
It's not a vexing parse because you used an integer literal rather than, say:
T myT(T());
As in this complete example:
#include <iostream>
struct T { int f() { return 1; } };
int main(int argc, char** argv) {
T t(T());
std::cout << t.f() << '\n';
return 0;
}
Which is ambiguous because it could mean:
myT
is aT
initialised with a default-constructedT
; ormyT
is a function returning aT
and taking one argument of typeT()
, which denotes a zero-argument function whose return type is alsoT
.
The latter interpretation is the default one, which is why a compiler error results from attempting to use the newly declared function as though it were the object you expected it to be.
See the Wikipedia article about it.
精彩评论