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?
>Solution :
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)) );