Bérenger
Bérenger

Reputation: 2748

destructor and unique_ptr

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

Answers (1)

Andy Prowl
Andy Prowl

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

Related Questions