2015-02-23 3 views
1

Итак, я хочу понять, разрешено ли для const_iterator (т. Е. Не изменяться) возвращать значение.Май оператор итератора * возвращает значение-значение?

То, что я обнаружил, что тип возвращаемого *r должен быть reference (1) где reference является iterator_traits<X>::reference (2). Именование ясно указывает на то, что обычно это должен быть ссылочный тип, но нужно ли это?

Есть ли разница между различными категориями итераторов в этом аспекте?

Все мои ссылки на стандарт (см. Ниже) относятся к n3242 (последняя версия с ++ 11, я считаю), но мне также интересно узнать разницу между версиями C++, если они есть.

(1) 24.2.2.2
(2) 24.2.1.11

+0

'const_iterator' должен возвращать' сопзЬ & ', так что вы не имеете дорогостоящие операции копирования. – NathanOliver

+3

Итератор для 'vector ' указывает на обертку. так да. – Jarod42

+0

@NathanOliver, точка не в копировании, а в возврате значения, которое находится в итераторе. – RiaD

ответ

3

вперед и сильнее итераторы, как предполагается, должны быть reference фактический ссылочный тип ([forward.iterators]/p1):

класс или указатель типа X удовлетворяет требованиям вперед итератора, если

  • [...]
  • если X является изменяемым итератором, reference является ссылкой на T; если X является константным итератором, reference является ссылкой на const T,
  • [...]

Входных итераторы могут иметь нереференсные reference s. istreambuf_iterator<charT>::reference, например, это charT.

Стандарт contradictory о том, что reference может быть для выходных итераторов. Чтобы процитировать связанную проблему с LWG, она «может и не может быть void».

Обратите внимание, что сам стандарт лежит: от N4140, vector<bool>::iterator должен быть случайным итератор доступа, но даже не удовлетворяет требованиям вперед итераторов, потому что его reference должен быть класс-оболочка, а не фактический тип ссылки , * Другой current proposal включает в себя больше лжи (см. bounds_iterator). не


* С правками, применяемых N4284, [vector.overview] больше не накладывает какие-либо требований по vector<bool>::iterator за найденными в таблице 96 - которая требует прямого итератора или сильнее, поэтому стандарт все еще лежит ,

0

В спецификации языка нет конкретного мандата, который оператор * должен возвращать что-либо в частности.

Очевидно, что правильная практика - вернуть ссылку, если оператор * используется как оператор разыменования, как обычно.

Boost xpressive является примером широко распространенной и хорошо известной библиотеки шаблонов, которая использует оператор * для возврата объекта, который представляет операцию сопоставления нескольких схожих слагаемых, ноль или более раз.

Документация здесь:

http://www.boost.org/doc/libs/1_57_0/doc/html/xpressive.html

Смежные вопросы