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

big*_*iao 1 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!
}
Run Code Online (Sandbox Code Playgroud)

我们都知道,当操作数本身是一个右值时,一个自定义的类operator --返回一个xvalue--Myclass().显然Myclass()prvalue,所以返回值也--Myclass()应该是rvalue(prcisely,xvalue).
来自cppref

am,对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员;

那么为什么auto在这种情况下推导左值引用呢?更重要的是,可以编译代码片段而不会出现任何错误!

为什么rvalue可以绑定到左值参考?

而且我遇到了一个令人困惑的错误(与上面的代码片段不一样,我确定矢量不是空的):后来当我使用时it, 发生了段故障!

导致段错误的代码(最后三行)这段代码是中文在线测试PAT的答案,当我提交答案时,会引起段错误.

是否使用左值引用绑定a 并在以后使用它是未定义的行为--Myclass()

eer*_*ika 6

我们都知道,operator --当我们编写类似的东西时,一个自定义的类返回一个右值--Myclass()

不,这不是我们所知道的.从技术上讲,用户定义的前缀减量运算符可以返回对象或引用.实际上,前缀递减运算符通常返回左值引用.

显然Myclass()是prvalue,所以返回值也--Myclass()应该是prvalue.

这不是价值类别传播的方式.你可以在prvalue上调用一个函数,函数可以返回一个左值(可能是*this).

那么为什么汽车会在这种情况下推断左值参考呢?

因为迭代器的递减运算符返回左值引用.


使用auto it来解决这个问题.


是否使用左值引用绑定a --Myclass()并在以后使用它是未定义的行为?

取决于如何Myclass::operator--()宣布.如果它返回左值引用,则表示为UB.如果它返回一个对象,那么就没有UB.可以提供由ref-qualifier重载的两个变体.