C ++:左值引用和右值引用的转换

时间:2016-01-22 16:15:07

标签: c++ c++14 rvalue-reference

我想知道标准的哪些部分在以下代码段中指定:

#include <memory>

class A { };

class B : public A { };

int main()
{
    std::unique_ptr<B> bptr = std::make_unique<B>(); // (a)
    std::unique_ptr<A> aptr = std::move(bptr);       // (b)
    std::unique_ptr<A> &aptr_r = bptr;               // (c)
    std::unique_ptr<A> &&aptr_rr = std::move(bptr);  // (d)
    return 0;
}

(d)编译,(c)不编译。请在答案中包含标准的相关部分或适当参考。仅供参考, Ubuntu clang版本3.6.2-1(标签/ RELEASE_362 / final)(基于LLVM 3.6.2)给了我

error: non-const lvalue reference to type 'unique_ptr<A>' cannot
       bind to a value of unrelated type 'unique_ptr<B>'
       std::unique_ptr<A> &aptr_r = bptr;
                           ^        ~~~~

gcc(Ubuntu 5.2.1-22ubuntu2)5.2.1 20151010 给了我

error: invalid initialization of reference of type ‘std::unique_ptr<A>&’
       from expression of type ‘std::unique_ptr<B>’
       std::unique_ptr<A> &aptr_r = bptr;
                                    ^

编辑:

为了使我的问题更清楚,请允许我添加

class C { };

std::unique_ptr<C> cptr = std::make_unique<C>(); // (e)
std::unique_ptr<A> &&aptr_rr2 = std::move(cptr); // (f)

什么是保持(f)编译时(d)?显然AC是无关的,但是当用于为(d)和(f)构造临时的std::unique_ptr构造函数

时检测到的位置
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u);

1 个答案:

答案 0 :(得分:4)

你的案例之间的关键区别在于rvalue引用可以间接绑定(通过临时),而非django/conf/locale/左值引用则不能。在(c)和(d)中,初始化程序不相似或可转换为[dcl.init.ref]/(5.1)中确定的类型,因此[dcl.init.ref] /(5.2)必须适用 - 立即排除( C):

  

否则,引用应该是对a的左值引用   非易失性const类型(即 cv1 应为const)或参考   应为右值参考。

另请注意,constunique_ptr<A>是不同的,不相关的类型,无论unique_ptr<B>A的关联方式如何。

您可以遵守该规则with scalars, too

B