2016-11-04 14 views
4

ライブラリのイテレータクラス(たとえば、MyIterator)を書いています。constイテレータと非constイテレータを作成する

std::vectoriteratorなどstd::vectorMyIteratorながら、行為のconst_iteratorよう const MyIterator行為をするためにconstのオーバーロードを使用することをお勧めしますか?

ライブラリのユーザー/開発者は混乱するでしょうか?代替のconstと非constイテレータに専門のできる単一のイテレータクラスを実装するためのテンプレートを使用することになり

// std::iterator example 
#include <iostream>  // std::cout 
#include <iterator>  // std::iterator, std::input_iterator_tag 

class MyIterator : public std::iterator<std::input_iterator_tag, int> 
{ 
    mutable int* p; 
public: 
    MyIterator(int* x) :p(x) {} 
    MyIterator(const MyIterator& mit) : p(mit.p) {} 
    MyIterator& operator++() {++p;return *this;} 
    MyIterator operator++(int) {MyIterator tmp(*this); operator++(); return tmp;} 
    bool operator==(const MyIterator& rhs) {return p==rhs.p;} 
    bool operator!=(const MyIterator& rhs) {return p!=rhs.p;} 
    const int& operator*() const {return *p;} // <-- const overload 
    int& operator*() {return *p;} 
}; 

:よう

実装は次のようになります。私は現在それをやっている(私はブーストがそれをやっていると聞いた...)。しかし、範囲を実装するとテンプレートが非常に迅速に複雑になり、範囲の範囲が(ループのネストされた範囲のように)広がります。

+1

地獄は 'mit'ですか?あなたの質問に答えるかもしれません。 – George

+1

@Georgeイテレーターが「ミット」と呼ばれるように私はそれを取る。おそらく 'my_iterator'の短縮形です。 – NathanOliver

+0

私は混乱するだろうが、それは私だけです。 – jrok

答えて

7
const_iteratorが一定イテレータであることを意図されていないため、動作しません const_MyIteratorconst_iterator)の代替として const MyIteratorを使用

が、定数素子を反復イテレータ。これらは、反復子自体を変更、非constメソッドであるため、

また、const MyIteratorで、あなたは、++または--のように、変更の演算子を使用できませんでした。

だから、const_iteratorのようなものを提供したいのであれば、それを回避することはできません。

ライブラリユーザー/開発者は混乱するでしょうか?

は最後に、あなたの質問に答えるために:はい、私は理由 const iteratorconst_iteratorの異なる行動(と期待)と、そう思います。

+0

それは働くことができます。イテレータを実装するときに、どの属性を変更可能なものとして定義する必要があります。私はそれが良い考えであるかどうか分からない。 –

+0

@dotdotdotそれは絶対にありません*良いアイデアです。何かが可能であるということだけがあなたがそれをするべきではありません。 –

+0

はい、そうです、それは技術的に可能です。しかし、それは混乱を招き、 'const'オブジェクトの動作の期待に反します。 –