Почему в STL
std::iterator_traits<const T*>::value_type
тот же тип, что и
std::iterator_traits<T*>::value_type
Почему так устроено? Не должно быть первым const T и второй только T? Как вы должны принять базовый константный правильный тип итератора? Я знаю, что вы можете написать свой собственный шаблон класса и специализацию и получить его от
std::iterator_traits<const T*>::pointer
но разве не должно быть члена typedef, который его содержит?
Это позволяет мне сделать это:
std::iterator_traits<I>::value_type val = *iter;
val += 5;
doSomething(val);
Но это сложнее, если value_type
это const, потому что мне нужно использовать remove_const
,
Если я не хочу получать изменяемое значение, то не имеет значения, value_type
является постоянным или нет:
const std::iterator_traits<I>::value_type cval = *iter;
std::iterator_traits<I>::reference ref = *iter;
Оба они работают для постоянных и неконстантных итераторов, и оба работают ли value_type
является const или нет, но первый пример работает только для const итераторов, если их value_type
неконстантен.
Как вы должны принять базовый константный правильный тип итератора?
Итератор не обязательно имеет собственный базовый тип, итератор обычно ссылается на некоторый диапазон или некоторую коллекцию, и именно эта коллекция имеет базовый тип. например std::list<int>::const_iterator
«s value_type
является std::list<int>::value_type
, который int
не const int
,
Вы не обязательно хотите знать, что является базовым типом, скорее всего, вы хотите знать, каков результат *iter
есть и вот что iterator_traits<I>::reference
говорит тебе.
Constness не имеет значения для типа значения, поскольку значение подразумевает копию. std::iterator_traits<const T*>::reference
это const T&
тем не мение.
Например, вы можете написать эту функцию:
template <class Iterator>
typename std::iterator_traits<Iterator>::value_type getValue(Iterator i)
{
return *i;
}
и это прекрасно работает, является ли Iterator const T *
или T *
,