Является decltype(*it)
тип значения итератора, или ссылка на это значение, или что-то еще?
Я думаю, что это ссылка на lvalue, потому что *it
это значение, но я не уверен.
Примечание: в моем случае it
это BidirectionalIterator, но не стесняйтесь отвечать на общий случай.
*it
не обязательно lvalue. Только прямые итераторы имеют это требование.
Итераторы (§24.2.2) должны иметь *it
быть верным выражением, которое возвращает iterator_traits<Iterator>::reference
(и другие не относящиеся к делу вещи). Больше ничего не сказано об этом и reference
не должен быть ссылочным типом †.
Входные итераторы (§24.2.3) должны иметь *it
быть верным выражением, которое возвращает что-то конвертируется в тип значения.
У прямых итераторов, однако, есть следующее требование (§ 24.2.5, параграф 1):
— если
X
изменчивый итератор,reference
это ссылка наT
; еслиX
является постоянным итератором,reference
это ссылка наconst T
,
(Вот T
тип значения итератора)
Это требует *it
быть ссылкой, что означает, что это должно быть glvalue (то есть не может быть prvalue, но может быть xvalue, как в случае с итераторами перемещения).
Более высокие категории итераторов не добавляют никаких соответствующих требований.
† reference
определяется как тип *it
что делает его немного круговым определением, но не ставит ограничений.
*it
наверняка не гарантируется быть lvalue. Входные итераторы могут возвращать значение.