This code causes compilation error (most vexing parse)
#include <iostream>
class A {
int a;
public:
A(int x) :a(x) {}
};
class B {
public:
B(const A& obj) { std::cout << "B\n";}
void foo() {std::cout << "foo\n";}
};
int main()
{
int test = 20;
B var(A(test)); //most vexing parse
var.foo();
return 0;
}
But if I pass 20
instead of test
(A(20)
instead of A(test)
), there is no compilation error.
#include <iostream>
class A {
int a;
public:
A(int x) :a(x) {}
};
class B {
public:
B(const A& obj) { std::cout << "B\n";}
void foo() {std::cout << "foo\n";}
};
int main()
{
int test = 20;
//B var(A(test));
B var(A(20)); //ok works fine
var.foo();
return 0;
}
Why is this not considered as most vexing parse? What is the difference between these two code versions?
A variable can be defined like
type(name)
Because of that
B var(A(test));
declares a function named var
that returns a B
and takes an A
named test
. In
B var(A(20));
if you tried to do the same thing, the A
parameter would be called 20
, which is not a valid variable name. Since it cannot be the name of a variable we know it is a value and instead we are constructing a variable named var
of type B
with the value of A(20)
.