iterator_const_reference_t is implemented as follows:
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>>;
But why? Why isn't it simply: std::add_const_t<std::iter_reference_t<T>>
?
add_const_t<int&>
will still be int&
, which is not a const reference. You probably mean const iter_value_t<T>&
but that might lead to dangling issues.
The formula in your question comes from range/v3 which has been around for years and can handle almost all cases including proxy references.
For example, the reference of zip_view
's iterator, namely tuple<int&, int&>
, cannot be made a const reference just by adding a top-level const
-qualifier.
In this case, we can apply common_reference
's specialization for tuple
to produce the correct reference type i.e. tuple<const int&, const int&>
, that's why the formula of iter_const_reference_t
has the common_reference
part.