Reputation: 68
I am confused by a compiler error I'm receiving with C++14. It concerns the necessity of a default constructor for member variables. In the code below, class A does not have a default constructor. class B has a member of type A that it move assigns. The compiler complains about the lack of default constructor for A, even though I'm not explicitly calling it anywhere. Is there some implicit call to the default constructor of A happening in the constructor of B that I'm missing? My understanding was that if you initialize the members of B in the constructor of B, then the default constructor is not necessary.
The code in main works fine when B is commented out. What is essentially the same thing in the constructor of B does not work.
Thank you,
#include <utility>
class A {
public:
A(int x) : _x{x} {}
A(A &&other) : _x{other._x} {}
A &operator=(A &&other) { _x = other._x; }
private:
int _x;
};
class B {
public:
B() {
A a(2);
_a = std::move(a);
}
private:
A _a;
};
int main() {
A b(1);
A a = std::move(b);
return 0;
}
~/move.cpp: In constructor ‘B::B()’:
~/move.cpp:17:7: error: no matching function for call to ‘A::A()’
B() {
^
~/move.cpp:7:3: note: candidate: A::A(A&&)
A(A &&other) : _x{other._x} {}
^
~/move.cpp:7:3: note: candidate expects 1 argument, 0 provided
~/move.cpp:5:3: note: candidate: A::A(int)
A(int x) : _x{x} {}
^
~/move.cpp:5:3: note: candidate expects 1 argument, 0 provided
Upvotes: 0
Views: 84
Reputation: 36
B() { <- tries to call A();
B() : _a(2) <- calls A(int x);
B() : _a(A(2)) <- Calls A(const A&) and A(int x)
B(A a) : _a(std::move(a)) <- calls A(A &&other)
Upvotes: 0
Reputation: 60208
Is there some implicit call to the default constructor of A happening in the constructor of B that I'm missing?
Yes. From the reference
Before the compound statement that forms the function body of the constructor begins executing, initialization of all direct bases, virtual bases, and non-static data members is finished.
(emphasis mine)
So in the constructor
B() {
// ^ here
before the opening brace, the member _a
is initialized. But since there's no default constructor, you get an error. You can avoid this by initializing it explicitly
B() : _a(42) {
Upvotes: 2