请参阅下面的代码段:
#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()?
我们都知道,
operator --当我们编写类似的东西时,一个自定义的类返回一个右值--Myclass()
不,这不是我们所知道的.从技术上讲,用户定义的前缀减量运算符可以返回对象或引用.实际上,前缀递减运算符通常返回左值引用.
显然
Myclass()是prvalue,所以返回值也--Myclass()应该是prvalue.
这不是价值类别传播的方式.你可以在prvalue上调用一个函数,函数可以返回一个左值(可能是*this).
那么为什么汽车会在这种情况下推断左值参考呢?
因为迭代器的递减运算符返回左值引用.
使用auto it来解决这个问题.
是否使用左值引用绑定a
--Myclass()并在以后使用它是未定义的行为?
取决于如何Myclass::operator--()宣布.如果它返回左值引用,则表示为UB.如果它返回一个对象,那么就没有UB.可以提供由ref-qualifier重载的两个变体.