kaylum
kaylum

Reputation: 14044

Return unique_ptr<Derived> in function which is declared to return unique_ptr<Base>

The code returns a unique_ptr<Derived> in function which is declared to return unique_ptr<Base>. I get an error when compiled with g++-4.8 but no error when compiled with g++-5.4 and g++-7. Is this a compiler bug with g++4.8 or have I done something wrong?

The code:

#include <memory>

class Base
{
public:
    Base() {}
};

class Derived: public Base
{
public:
    Derived() : Base() {}
};

std::unique_ptr<Base> func()
{
    std::unique_ptr<Derived> derivedPtr = std::unique_ptr<Derived>();
    return derivedPtr;
}

int main()
{
    std::unique_ptr<Base> basePtr = func();

    return 0;
}

The error with g++-4.8:

$ g++-4.8 -std=c++11 test.cpp
test.cpp: In function ?std::unique_ptr<Base> func()?:
test.cpp:19:9: error: cannot bind ?std::unique_ptr<Derived>? lvalue to ?std::unique_ptr<Derived>&&?
  return derivedPtr;
         ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from test.cpp:2:
/usr/include/c++/4.8/bits/unique_ptr.h:169:2: error:   initializing argument 1 of ?std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Up, _Ep>&&) [with _Up = Derived; _Ep = std::default_delete<Derived>; <template-parameter-2-3> = void; _Tp = Base; _Dp = std::default_delete<Base>]?
  unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept

  ^

No error with g++-7:

$ g++-7 -std=c++11 test.cpp
$ 

If I change func to return std::move(derivedPtr); then the code compiles on all the g++ versions. Though I would like to understand whether my original code is valid or not.

Upvotes: 1

Views: 142

Answers (2)

Jarod42
Jarod42

Reputation: 218323

The is CWG 1579 which applies retroactively to C++11, but old compiler versions might miss that.

Upvotes: 1

bitmask
bitmask

Reputation: 34714

From the status documentation of gcc for compiler features, you can tell that C++11 features were being implemented between gcc versions 4.3 through 4.8.1.

In fact the status page states:

GCC 4.8.1 was the first feature-complete implementation of the 2011 C++ standard, previously known as C++0x.

Unfortunately there isn't such a handy page for the standard library implementation, but it stands to reason that the implementation of features in the library roughly parallels that of the language features in the compiler itself.

So, it is entirely reasonable that the version of the standard library in version 4.8 is not feature complete, just as the compiler wasn't.

Upvotes: 3

Related Questions