Suppose I have classes A, B:
class A
{
int a;
public:
A(int a) : a(a) { }
};
class B
{
A a;
public:
B(A a) : a(a) { }
};
And I want to create an instance of B as:
int i = 1;
B b(A(i));
But when I actually try to use b, I get the problem described here. That is, b is not an instance of B, it's a function that returns an object of type B. However, it's a different case from the linked question, and I can't figure out why it's happening here.
I could create B as:
int i = 1;
A a(i);
B b(a);
Or even as:
B b(A(1));
And it'll work. However, in the real case the first option requires too many lines, and the second option requires very long line (because instead of int I have an object which needs to be constructed, and I have a chain of some objects). How can I create the int in his own line, and then create A and B in the same line?
CodePudding user response:
The problem is that B b(A(i));
is a function declaration and not a declaration for a variable named b
of type B
.
This is due to what is called most vexing parse. In particular, the statement:
B b(A(i)); //this is a declaration for a function named `b` that takes parameter of type A and has no return type
the above is a declaration for a function named b
that takes one parameter of type A
and with return type of B
.
To solve this, you can either use curly braces {}
or double ()
to solve this:
Method 1
Use {}
around A(i)
.
//----v----v------->declares a variable of type B and is not a function declaration
B b{A(i)};
Method 2
Use double parenthesis (())
.
//-v--------v------>declares a variable of type B and is not a function declaration
B b( (A(i)) );
CodePudding user response:
One obvious way to rule out any possible function declaration is:
B b { A {i} };