AFAIK 获取右值的地址是非法的,因为地址运算符&
获取一个左值并返回对象调用地址的地址。
这是一个我试图理解但发现它有点混乱的例子:
#include <deque>
#include <iostream>
int main() {
using std::cout;
using std::endl;
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 };
std::deque<int>::iterator it = di.end() - 1;
cout << *it << endl;
cout << &it-- << endl; // is it UB?
cout << *it << endl;
cout << &it-- << endl;
cout << *it << endl;
cout << &it-- << endl;
cout << *it << endl << endl;
cout << &--it << endl; // ok
cout << *it << endl; // ok
cout << &--it << endl; // ok
cout << *it << endl; // ok
std::cout << std::endl << "done!" << std::endl;
}
在我使用预减运算符的行中,它是可以的,因为该运算符
&
具有相同的优先级,并且从右到左(RL)进行评估,因此--
首先评估并返回一个左值(也采用左值) . then&
被评估,所以&
左值是可以的。上述后减运算符中的问题,它接受一个左值并返回一个右值,并且优先级高于
&
. 因此,在这些表达式中,我调用&
了通常不允许的右值。但是为什么代码编译并给出不同的结果(地址)?在带有标志的 Wandbox 上编译时,
-pedantic
它不会编译:prog.cc:25:17: error: taking address of rvalue [-fpermissive] 25 | cout << &offEnd-- << endl; // -- has higher precedence than & thus this expression decrements offEnd and returns a copy of original of offEnd then print the address of this original object (before decrementing it)
也在 MSVC++14 上使用
/Wall
.那么它是我的代码中未定义的行为吗?
- 那么为什么 C++ 允许
&
在右值上调用运算符的地址而标准不允许呢? - 最后我想知道这些不同的地址在这样的表达中来自哪里:
std::cout << &it-- << std::endl;
?但是取消引用的值是正确的!