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

C++ C++;:左值引用和右值引用的转换,c++,c++14,rvalue-reference,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::uniq

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

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

两种情况之间的关键区别在于,右值引用可以间接绑定(通过临时绑定),而非const左值引用则不能。在(c)和(d)中,初始值设定项与中确定的类型不相似或不可转换,因此[dcl.init.ref]/(5.2)必须适用-立即排除(c):

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

还要注意,
unique\u ptr:

(c)
不编译,因为
aptr\u r
bptr
的类型不同,因此
aptr\u
不能成为
bptr
的参考。它是这样的:
intx=0;浮动&y=x。但是
(d)
编译,因为目标类型的临时对象是从表达式
std::move(bptr)
中创建的。。临时对象绑定到右值引用。请注意,创建此右值引用后,
bptr
将变为null,因为它已被移动。
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;
                           ^        ~~~~
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)
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u);
int&& i = 0.f; // Ok
int& i = 0.f; // Not ok