为什么const/nonconst lvalue引用与rvalue参考结合

Why both const/nonconst lvalue references bind to a rvalue reference?

本文关键字:rvalue 参考 结合 引用 lvalue const nonconst 为什么      更新时间:2023-10-16

允许此非常简单的代码:

class s
{
public:
};
const s& tt = std::move(s()); // Also valid without 'const'

但是现在我想知道为什么允许它..

首先,我们使用 std::move并标记rvalue(临时)作为rvalue参考,但是为什么lvalue参考可以绑定到rvalue参考?

是因为rvalue参考也是rvalue?

是什么理由(或标准报价)导致LVALUE参考绑定到rvalue参考?>

编辑:MSVC2015允许非const lvalue引用绑定到rvalue参考文献,该问题仍然是与rvalue参考的const lvalue参考。抱歉,我应该指定我使用的编译器。

rvalue引用被隐式转换为rvalues(更具体地说,是xvalues),作为标准转换之一(C 标准的第4章):

>

任何隐式转换的效果与执行 相应的声明和初始化,然后使用 临时变量是转换的结果。结果是 lVALUE如果t是lvalue参考类型或rvalue参考 函数类型(8.3.2), xValue如果t是对object的rvalue引用 type 和prvalue否则

rvalues(包括xvalues)可以绑定到 const lvalue参考文献,以便您可以将临时性传递给具有此类参数的函数:

void foo(const bar &a);
// ...
foo(bar());

(临时是rvalue;在这种情况下, bar()的结果是rvalue)。没有理由不是允许这样做的,因为临时性始终只有包含表达方式 - 在这种情况下,函数调用 - 因此它不会在foo中创建悬空的参考。p>这意味着可以始终将功能fun(bar)的签名调整为fun(const bar &)-并当然可以相应地更改实现! - 由于临时论点仍将被接受,并且从呼叫者的角度来看,语义应该是相同的;const表示不会修改该对象,如果该对象通过复制传递。

const不允许参考;一个实际原因是因为它们暗示该值应以某种有意义的方式修改,如果值是暂时的,则将丢失。但是,如果您真的想使用一些警告,则可以将RVALUE转换为LVALUE,如此答案中所述。

允许RVALUE与const LVALUE参考结合,除了允许通过参考传递临时参数以外,对于不知道确切的参数类型但您希望在可能的情况下允许移动语义的情况也有好处。假设我正在调用一个可以定义为foo2(const bar &)foo2(bar)的函数,并且在前一种情况下可能会或可能没有过载foo2(bar &&),并且我想在可能的情况下使用移动语义(假设foo2(bar &&) Overload使用将使用Move Senantics在实施中移动语义);我可以安全地使用std::move来创建RVALUE,因为它在任何一种情况下都将应用。这个示例似乎有些人为人为,但是在编写模板时,这种示例可能会出现很多。在代码中:

bar bb = bar();
foo2(std::move(bb));
// above is legal if foo2 is declared as either:
//    foo2(bar)
//    foo2(const bar &)
// and in latter case calls overload foo2(bar &&) if it is defined.

对于涉及临时性的其他rvalue-to-lue-value-reference分配分配,临时的寿命将延长到参考文献的寿命,因此即使在参数传递以外的上下文中也不会创建悬挂的参考文献:

const bar &b = bar(); // temporary lifetime is extended

在上面,bar对象将在参考b脱离范围之前不会被破坏。