请参阅下面的代码段:
#include<vector>
using std::vector;
int main()
{
vector<int> a;
auto &&it=--a.end();//what?the hint tell me it deduces a lvalue reference type!
}
我们都知道,当操作数本身是右值时,operator --
的自定义类会返回 xvalue ,例如--Myclass()
。显然Myclass()
是 prvalue ,因此--Myclass()
的返回值也应该是 rvalue (prcisely,xvalue)。
来自cppref
a.m,对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员;
那么为什么auto
在这种情况下推导左值引用呢?
更重要的是,可以编译代码片段而不会出现任何错误!
为什么rvalue可以绑定到左值参考?
我遇到了一个令人困惑的错误(与上面的代码片段不一样,我确定该向量不为空):稍后当我使用it
时,段错误< / strong>发生了!
The code that causes segment fault(在最后三行)此代码是中文在线测试PAT的答案,当我提交答案时,它会引起段错误。
是未定义的行为使用左值引用来绑定--Myclass()
,并在以后使用它?
答案 0 :(得分:6)
我们都知道,当我们写
之类的东西时,operator --
--Myclass()
的自定义类会返回右值
不,这不是我们所知道的。从技术上讲,用户定义的前缀减量运算符可以返回对象或引用。实际上,前缀递减运算符通常返回左值引用。
显然
Myclass()
是prvalue,因此--Myclass()
的返回值也应该是prvalue。
这不是值类别传播的方式。你可以在prvalue上调用一个函数,函数可以返回一个左值(可能是*this
)。
那么为什么在这种情况下自动推导左值引用呢?
因为迭代器的递减运算符返回左值引用。
使用auto it
解决问题。
使用左值引用绑定
--Myclass()
并稍后使用它是不确定的行为?
取决于Myclass::operator--()
的声明方式。如果它返回左值引用,则表示为UB。如果它返回一个对象,那么就没有UB。可以提供由ref-qualifier重载的两种变体。
答案 1 :(得分:-6)
这是"universal reference"。变量不是rvalue引用,而是rvalue移动到的左值。这是必要的,因为引用不会延长临时对象的生命周期。