In the C++ standard library, why is
std::iterator_traits<const T*>::value_type
the same type as
std::iterator_traits<T*>::value_type
Why it is designed like that? Shouldn't the first be const T
and the second only T
? How are you supposed to take the underlying const-correct type of an iterator? I know you can write your own template class and specialization and get it from
std::iterator_traits<const T*>::pointer
but shouldn't there be a member typedef that holds it?
It allows me to do this:
std::iterator_traits<I>::value_type val = *iter;
val += 5;
doSomething(val);
But that's harder if value_type
is const, because I need to use remove_const
.
If I don't want to get a modifiable value then it doesn't matter whether value_type
is const or not:
const std::iterator_traits<I>::value_type cval = *iter;
std::iterator_traits<I>::reference ref = *iter;
Both of these work for const iterators and non-const iterators, and both work whether value_type
is const or not, but the first example only works for const iterators if their value_type
is non-const.
How are you supposed to take the underlying const correct type of an iterator?
An iterator doesn't necessarily have an underlying type of its own, an iterator usually refers to some range or some collection, and that collection is what has an underlying type. e.g std::list<int>::const_iterator
's value_type
is std::list<int>::value_type
, which is int
not const int
.
You don't necessarily want to know what the underlying type is anyway, it's more likely you want to know what the result of *iter
is, and that's what iterator_traits<I>::reference
tells you.