Зачем вызывать адрес оператора на rvalues? - PullRequest
3 голосов
/ 21 сентября 2019

AFAIK, запрещено принимать адрес значения r, потому что оператор адреса & принимает значение l и возвращает адрес вызываемого объекта по адресу.

Вот примерпопытался понять, но нашел это немного запутанным:

#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), поэтому -- вычисляется первым и возвращает lvalue (принимает также lvalue).тогда & вычисляется так, что & для lvalue в порядке.

  • Проблема выше в операторе пост-декремента, который принимает lvalue и возвращает значение r и имеет более высокий приоритет над&.Поэтому в этих выражениях я звоню & на значение rvalue, которое обычно не допускается.Но почему код компилируется и дает разные результаты (адреса) ??

  • При компиляции в 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 ++ допускает вызывающий адрес оператора & на rvalue, в то время как стандарт запрещает это?
  • Наконец, я хочу знать, откуда поступают разные адреса в таком выражении: std::cout << &it-- << std::endl;?Но значения разыменования верны!
...