Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回唯一\u ptr<;派生>;在声明为返回唯一的函数中\u ptr<;基地>;_C++ - Fatal编程技术网

C++ 返回唯一\u ptr<;派生>;在声明为返回唯一的函数中\u ptr<;基地>;

C++ 返回唯一\u ptr<;派生>;在声明为返回唯一的函数中\u ptr<;基地>;,c++,C++,代码在函数中返回一个unique\u ptr,该函数被声明为返回unique\u ptr。使用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\u ptr
,该函数被声明为返回
unique\u ptr
。使用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;
}
如果我将
func
更改为
返回std::move(derivedPtr)然后代码在所有
g++
版本上编译。尽管我想了解我的原始代码是否有效。

从for编译器功能中,您可以看出C++11功能是在gcc版本4.3到4.8.1之间实现的

事实上,状态页面说明:

GCC 4.8.1是2011年的第一个功能完整实现 C++标准,以前称为C++ 0x.</P> 不幸的是,对于标准库实现来说,没有这样一个方便的页面,但是很显然,库中功能的实现与编译器本身的语言功能的实现大致相同

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

从编译器功能的版本中,可以看出C++11功能是在gcc版本4.3到4.8.1之间实现的

事实上,状态页面说明:

GCC 4.8.1是2011年的第一个功能完整实现 C++标准,以前称为C++ 0x.</P> 不幸的是,对于标准库实现来说,没有这样一个方便的页面,但是很显然,库中功能的实现与编译器本身的语言功能的实现大致相同


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

追溯适用于C++11的is,但旧编译器版本可能会忽略这一点。

追溯适用于C++11的is,但是旧的编译器版本可能会忽略这一点。

新的编译器附带了新的功能,只需使用新的功能就可以了?它从来没有那么简单,不是吗?所讨论的真正代码库已通过特定编译器版本的鉴定,虽然升级并非不可能,但该过程将非常重要。无论如何,我想了解代码是否有效。只是出于好奇(幸运的是,我不是猫),如果您将
func
修改为
return std::move(derivedPtr),会发生什么情况?在中找到。新的编译器具有新的功能,只需使用新的功能即可?它从来没有那么简单,是吗?所讨论的真正代码库已通过特定编译器版本的鉴定,虽然升级并非不可能,但该过程将非常重要。无论如何,我想了解代码是否有效。只是出于好奇(幸运的是,我不是猫),如果您将
func
修改为
return std::move(derivedPtr),会发生什么情况?在中找到。谢谢!我不知道4.8会落在这个差距里。这与@jarod42的问题链接一起解释了很多。可能相关的是,
clang cl
在OP的原始代码上给出了这个警告:警告:在根据ISO C++11解决缺陷报告之前,局部变量“derivedPtr”会被复制,尽管它是按名称返回的,因为它与函数返回类型不匹配('unique_ptr'vs'unique_ptr')[-Wreturn-std-move-in-c++11]。请参见编辑。第一个功能完整的版本是4.8.1而不是4.9。但4.8仍然比4.8.1旧。谢谢!我不知道4.8会出现这种差距。这与@jarod42的问题链接一起解释了很多。可能相关的
clang cl
在OP的原始代码上给出了以下警告:警告:在解决缺陷报告之前在ISO C++11中,局部变量“derivedPtr”虽然按名称返回,但仍会被复制,因为它与函数返回类型不匹配(“unique_ptr”vs“unique_ptr”)[-Wreturn-std-move-in-C++11]。请参见编辑。第一个功能完整版本是4.8.1而不是4.9。但4.8仍然比4.8.1旧。
$ 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 -std=c++11 test.cpp
$