Reputation: 2748
I have the following code
class A {
public:
A(){}
~A(){}
private:
std::vector<std::unique_ptr<double> > x;
};
A f() {
A a;
return a;
}
int main() {
A a=f();
return 0;
}
It does not compile (gcc 4.7), unless I comment out the destructor. Actually, I don't really need this destructor in my code, I just wanted to use it for debug purpose.
However, I don't understand what is happening and I therefore fear I have done something wrong. What is happening here ?
Upvotes: 25
Views: 6855
Reputation: 126432
That is because the presence of an explicitly defined destructor prevents the implicit generation of a move constructor for A
.
Per Paragraph 12.8/9 of the C++11 Standard:
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
— X does not have a user-declared copy constructor,
— X does not have a user-declared copy assignment operator,
— X does not have a user-declared move assignment operator,
— X does not have a user-declared destructor, and
— the move constructor would not be implicitly defined as deleted.
Now without a move constructor, to return the value from f()
the compiler will try to invoke the implicitly generated copy constructor (which is still being generated for backwards compatibility). However, std::unique_ptr
is non-copyable. Hence, the error.
Explicitly defining a move constructor (or declaring one as defaulted, as suggested by juanchopanza in the comments) will fix the problem.
Upvotes: 32