Возвращают ли постфиксные операторы lvalue при применении к ostream_iterator?

Разве следующий код, приведенный в C++ Primer, неверен?

ostream_iterator<int> out_iter(cout, " ");
for (auto e : vec)
    *out_iter++ = e;  // the assignment writes this element to cout
cout << endl;

Постфиксный оператор возвращает старое значение, а не ссылку, тогда как его можно заставить действовать как lvalue?

Пожалуйста, поправьте, если я ошибаюсь


person Gaurav Pant    schedule 28.12.2017    source источник
comment
out_iter++ не является lvalue. Это rvalue итератора. *out_iter++ является lvalue.   -  person n. 1.8e9-where's-my-share m.    schedule 28.12.2017
comment
Вы неправильно понимаете приоритет оператора. *out_iter++ означает *(out_iter++), а не (*out_ptr)++.   -  person Raymond Chen    schedule 28.12.2017
comment
@н.м. Уверены ли вы? Насколько я понимаю, out_iter++ тоже является lvalue.   -  person Edgar Rokjān    schedule 28.12.2017
comment
@EdgarRokyan, вы правы, ++ здесь возвращает ссылку, поэтому это lvalue, но только потому, что это итератор ostream. Другие итераторы этого не делают.   -  person n. 1.8e9-where's-my-share m.    schedule 28.12.2017


Ответы (2)


Согласно ссылке http://en.cppreference.com/w/cpp/iterator/ostream_iterator/operator_arith

ostream_iterator& оператор++();

ostream_iterator& оператор++(int);

но оператор* и операторы ++ для ostream_iterator ничего не делают, они только возвращают ссылку на *this, поэтому вы можете написать это

for (auto e : vec)
    out_iter = e;  // the assignment writes this element to cout

и вывод будет тот же.

person rafix07    schedule 28.12.2017

Код в порядке, как:

*out_iter++ = e;

равно:

*(out_iter++) = e;

поэтому сначала происходит приращение постфикса, а затем выполняется разыменование.

Из operator++:

ostream_iterator& operator++();
ostream_iterator& operator++( int );

Ничего не делает. Они позволяют использовать выражения *iter++=value и *++iter=value для вывода (вставки) значения в базовый поток.

Возвращаемое значение

*это

Из operator*:

ostream_iterator& operator*();

Он возвращает сам итератор, что позволяет использовать такой код, как *iter = value, для вывода (вставки) значения в базовый поток.

Возвращаемое значение

*это

По сути, это означает, что *(out_iter++) возвращает ссылку на сам итератор, поэтому можно писать в поток в виде *(out_iter++) = value.

person Edgar Rokjān    schedule 28.12.2017