STLコンテナーの代わりに使用されているコンテナーのイテレーターを作成しています。現在、STLコンテナは c ++ 11 foreach構文 で多くの場所で使用されています。例:for(auto &x: C)
。 STLコンテナをラップするカスタムクラスを使用するには、コードを更新する必要があります。
template< typename Type>
class SomeSortedContainer{
std::vector<typename Type> m_data; //we wish to iterate over this
//container implementation code
};
class SomeSortedContainerIterator{
//iterator code
};
コードを次の方法で呼び出すことができるように、カスタムコンテナの正しいイテレータを自動で使用するにはどうすればよいですか?
SomeSortedContainer C;
for(auto &x : C){
//do something with x...
}
一般に、autoがクラスに正しい反復子を使用することを保証するために何が必要ですか?
次の2つの選択肢があります。
begin
およびend
という名前のメンバー関数を提供します。これらは、C.begin()
およびC.end()
;のように呼び出すことができます。begin
およびend
という名前の無料の関数を提供します。これらの関数は、引数依存のルックアップを使用して、または名前空間std
で見つけることができ、begin(C)
およびend(C)
。範囲ベースのforを使用できるようにするには、クラスでconst_iterator begin() const
およびconst_iterator end() const
メンバーを提供する必要があります。グローバルbegin
関数をオーバーロードすることもできますが、私の意見では、メンバー関数を使用する方が適切です。 iterator begin()
およびconst_iterator cbegin() const
も推奨されますが、必須ではありません。単一の内部コンテナを繰り返し処理するだけの場合、それは非常に簡単です。
template< typename Type>
class SomeSortedContainer{
std::vector<Type> m_data; //we wish to iterate over this
//container implementation code
public:
typedef typename std::vector<Type>::iterator iterator;
typedef typename std::vector<Type>::const_iterator const_iterator;
iterator begin() {return m_data.begin();}
const_iterator begin() const {return m_data.begin();}
const_iterator cbegin() const {return m_data.cbegin();}
iterator end() {return m_data.end();}
const_iterator end() const {return m_data.end();}
const_iterator cend() const {return m_data.cend();}
};
ただし、カスタムをイテレートする場合は、コンテナー内のクラスとして独自のイテレーターを設計する必要があります。
class const_iterator : public std::iterator<random_access_iterator_tag, Type>{
typename std::vector<Type>::iterator m_data;
const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {}
public:
const_iterator() :m_data() {}
const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {}
//const iterator implementation code
};
イテレータクラスの記述の詳細については、 my answer here を参照してください。
他の人が述べたように、コンテナはbegin()
およびend()
関数を実装する必要があります(または、コンテナのインスタンスをパラメータとして取るグローバルまたはstd::
関数が必要です)。
これらの関数は同じ型を返す必要があります(通常はcontainer::iterator
ですが、これは単なる規則です)。返される型は、operator*
、operator++
、およびoperator!=
を実装する必要があります。
私の知る限り、SomeSortedContainer
はbegin()
とend()
を提供する必要があります。そして、これらは標準準拠のフォワードイテレータを返すはずです。あなたの場合はSomeSortedContainerIterator
で、実際にはstd::vector<Type>::iterator
。標準準拠では、通常のインクリメント演算子と逆参照演算子を提供する必要がありますが、すべてのvalue_type
、reference_type
、... typedefs。これは、コンテナ要素の基本型を決定するためにforeach構造体によって順番に使用されます。ただし、std::vector<Type>::iterator
。