I have a class A that accepts class B as a constructor parameter. Class B can be constructed from int value. My original code is quite complex, but I hope I've reduced it to the very base case:
class B {
public:
explicit B(int a) : val(a) {}
private:
int val;
};
class A {
public:
A(const B & val) : value(val) {};
void print() {
//does nothing
}
private:
B value;
};
int main() {
int someTimeVar = 22;
A a(B(someTimeVar));
a.print();
}
And this is the error code I'm getting:
$ g++ test.cpp -Wall -O0
test.cpp: In function ‘int main()’:
test.cpp:22:7: error: request for member ‘print’ in ‘a’, which is of non-class type ‘A(B)’
a.print();
^
test.cpp:20:9: warning: unused variable ‘someTimeVar’ [-Wunused-variable]
int someTimeVar = 22;
^
I use GCC (4.9.2 20150304 (prerelease)), platform: arch linux.
The following modification to the main function compiles fine:
int main() {
A a(B(22));
a.print();
}
I'm well aware that using A a(); declares a function, not a object. But I didn't expect that A a(B(some_val)) will do the same, and in my opinion this is what's happening here.
Do you have ideas why this is happening?
Edit: Thank you for all the answers, looks like I need to research more on most vexing parse idea.
BTW it turns out that compiling my code using clang provides more useful error message plus a solution:
$ clang test.cpp
test.cpp:21:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
A a(B(someTimeVar));
^~~~~~~~~~~~~~~~
test.cpp:21:9: note: add a pair of parentheses to declare a variable
A a(B(someTimeVar));
^
( )
test.cpp:22:6: error: member reference base type 'A (B)' is not a structure or union
a.print();
~^~~~~~
1 warning and 1 error generated.
This problem has its own tag here on stackoverflow. most-vexing-parse
Wikipedia har a clear description of the problem and its solution. https://en.wikipedia.org/wiki/Most_vexing_parse.
The solution is to add parenthesis to the argument like:
or as others have noted use universal initialization like