18

なぜSTLで

std::iterator_traits<const T*>::value_type

と同じタイプです

std::iterator_traits<T*>::value_type

なぜそのように設計されているのですか?最初のものはconst Tで、2番目のものはTのみであるべきではありませんか? イテレータの基礎となる const の正しい型をどのように取得することになっていますか? 独自のテンプレート クラスと特殊化を記述して、

    std::iterator_traits<const T*>::pointer

しかし、それを保持するメンバー typedef があるべきではありませんか?

4

2 に答える 2

16

値はコピーを意味するため、定数は値の型には関係ありません。ただし、ですstd::iterator_traits<const T*>::referenceconst T&

たとえば、次の関数を記述できます。

template <class Iterator>
typename std::iterator_traits<Iterator>::value_type getValue(Iterator i)
{
  return *i;
}

Iterator が aconst T *か aかに関係なく、完全に正常に動作しT *ます。

于 2012-10-10T12:37:14.953 に答える
13

これにより、次のことが可能になります。

std::iterator_traits<I>::value_type val = *iter;
val += 5;
doSomething(val);

しかし、value_typeconst を使用する必要があるため、それはより困難ですremove_const

変更可能な値を取得したくない場合は、 value_typeconst であるかどうかは関係ありません。

const std::iterator_traits<I>::value_type cval = *iter;
std::iterator_traits<I>::reference        ref  = *iter;

これらは両方とも定数反復子と非定数反復子に対して機能し、どちらも定数であるかどうかに関係value_typeなく機能しますが、最初の例は定数反復子value_typeが非定数である場合にのみ機能します。

イテレータの基礎となる const の正しい型をどのように取得することになっていますか?

反復子は必ずしもそれ自体の基になる型を持っているとは限りません。通常、反復子は何らかの範囲またはコレクションを参照し、そのコレクションは基になる型を持つものです。例:std::list<int>::const_iteratorvalue_typeisstd::list<int>::value_typeで、どちらはintnotconst intです。

*iterとにかく、基礎となる型が何であるかを必ずしも知りたいとは限りません。結果が何であるかを知りたい可能性が高く、それがあなたにiterator_traits<I>::reference伝えます。

于 2012-10-10T14:01:22.700 に答える