0

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?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
David Doria
  • 9,873
  • 17
  • 85
  • 147

1 Answers1

1

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);
  • unique_ptr is nullptr by default, too, right? Is it good or bad practice to either explicitly set it to nullptr or not? – David Doria Feb 27 '16 at 00:11
  • 1
    @DavidDoria Yes, that is the default. I can think of valid arguments for and against explicitly providing an initialiser and don't recall seeing consensus on a best practice. –  Feb 27 '16 at 00:18
  • Care to ouline them in 600 characters or less :) ? – David Doria Feb 27 '16 at 00:18
  • @DavidDoria For: some types are left uninitialised by default. As it's not always obvious whether a type would be left uninitialised, all class members should be initialised explicitly. Against: the unnecessary initialisers may cause clutter and detract from the logic that's more worthy of reading. –  Feb 27 '16 at 00:45