In-class member initializer of unique_ptr to nullptr error with explicitly defined default constructor

1.3k views Asked by At

I have a class template that assigns a unique_ptr to nullptr using an in-class member initializer. If I use MyClass(){}, all is well. If I use MyClass() = default, I get:

conversion from 'std::nullptr_t' to non-scalar type 'std::unique_ptr<A>' requested

Here is a minimal example which fails to compile with g++ 4.8.4:

#include <memory>

class A{};

template <typename T>
class Test
{
    std::unique_ptr<A> data = nullptr;
public:

    //Test() {} // works fine
    Test() = default; // compiler error

};

int main()
{
    Test<float> test;
}

Any ideas?

1

There are 1 answers

5
AudioBubble On BEST ANSWER

As pointed out in the comments already, this is a compiler bug. It's not a problem in the library implementation of unique_ptr, but a language issue that is fully reproducable without any standard library headers, seemingly only in class templates:

struct A { A(int); };
struct B { A a = 1; };
B b; // ok
template <typename T> struct C { A a = 1; };
C<void> c; // error

Luckily, it's a compiler bug that you can work around. The implicit conversion is mishandled. Force an explicit conversion and even GCC 4.8 accepts it. In your case, that means:

std::unique_ptr<A> data = std::unique_ptr<A>(nullptr);