在声明为返回unique_ptr <Base>的函数中返回unique_ptr <Derived>

时间:2020-04-18 12:08:10

标签: c++

代码在函数中返回一个unique_ptr<Derived>,该函数声明为返回unique_ptr<Base>。使用g ++-4.8编译时出现错误,但是使用g ++-5.4和g ++-7编译时没有错误。这是g ++ 4.8的编译器错误,还是我做错了什么?

代码:

#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;
}

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

  ^

g ++-7没有错误:

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

如果将func更改为return std::move(derivedPtr);,则代码将在所有g++版本上编译。虽然我想了解我的原始代码是否有效。

2 个答案:

答案 0 :(得分:3)

status documentation of gcc的编译器功能中可以看出,在gcc版本4.3到4.8.1之间已经实现了C ++ 11功能。

实际上,状态页面显示:

GCC 4.8.1是2011年的第一个功能完整的实现 C ++标准,以前称为C ++ 0x。

不幸的是,标准库的实现没有那么方便的页面,但是,有道理,库中功能的实现与编译器本身的语言功能大致相似。

因此,完全合理的是4.8版中的标准库的功能不完整,就像编译器没有那样。

答案 1 :(得分:1)

CWG 1579,它追溯适用于C ++ 11,但是旧的编译器版本可能会错过它。