为什么在使用auto&& it = - vec.end()时自动推导左值引用,是UB吗?

时间:2018-03-15 10:46:25

标签: c++ c++11

请参阅下面的代码段:

#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(),并在以后使用它?

2 个答案:

答案 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移动到的左值。这是必要的,因为引用不会延长临时对象的生命周期。