将std :: unique_ptr <Derived>转换为std :: unique_ptr <Base>

met*_*tal 41 c++ unique-ptr c++11 c++14

假设我有处理基类和派生类的工厂函数:

#include <memory>

using namespace std;

struct B { virtual ~B() {} };
struct D : B {};

unique_ptr<B> MakeB()
{
    auto b = unique_ptr<B>( new B() );
    return b; // Ok!
}

unique_ptr<B> MakeD()
{
    auto d = unique_ptr<D>( new D() );
    return d; // Doh!
}
Run Code Online (Sandbox Code Playgroud)

在上面的最后一行,我需要move(d)为了使它工作,否则我得到"错误:无效转换std::unique_ptr<D>std::unique_ptr<D>&&." 我的直觉说,在这种情况下,编译器应该知道它可以隐式地创建d一个rvalue并将其移动到基指针中,但事实并非如此.

这在我的编译器(gcc 4.8.1和VS2012)中是不可靠的吗?预期的设计unique_ptr?标准有缺陷吗?

Sim*_*ple 34

编译器的行为是正确的.当类型相同时,只有一个隐式移动,因为隐式移动是根据编译器在实际允许的情况下无法执行复制省略来指定的(参见12.8/31和12.8/32).

12.8/31(复制省略):

在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称. ..

12.8/32(隐含举动):

当满足复制操作的省略标准时,首先执行重载决策以选择复制的构造函数,就像对象由rvalue指定一样.

  • +1,但请注意,这已针对C++ 14进行了更改,[DR 1579](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3833.html#1579 )在上次会议上获得批准. (23认同)