iterator_const_reference_t é implementado da seguinte forma:
template<std::indirectly_readable T>
using iter_const_reference_t = std::common_reference_t<const std::iter_value_t<T> &&,
std::iter_reference_t<T>>;
Mas por que? Por que não é simplesmente: std::add_const_t<std::iter_reference_t<T>>
?
add_const_t<int&>
ainda seráint&
, o que não é uma referência const. Você provavelmente quer dizerconst iter_value_t<T>&
, mas isso pode levar a problemas pendentes.A fórmula na sua pergunta vem do range/v3 que existe há anos e pode lidar com quase todos os casos, incluindo referências de proxy.
Por exemplo, a referência do
zip_view
iterador de , ou sejatuple<int&, int&>
, , não pode ser transformada em uma referência const apenas adicionando umconst
qualificador de nível superior.Neste caso, podemos aplicar
common_reference
a especialização de paratuple
produzir o tipo de referência corretotuple<const int&, const int&>
, ou seja, é por isso que a fórmula deiter_const_reference_t
possui acommon_reference
parte.