c++c++11unique-ptrexplicit-constructorin-class-initialization

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


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?


Solution

  • 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);