とにかく何を達成しようとしていますか...あなたのクラスには内部ストレージがありますか、それとも数列の表現だけですか?
もしそうなら、問題は演算子T &operator*()
でT *operator->()
あり、イテレータが指す値を変更することができます。ただし、範囲クラスのみの場合は、明らかにこの方法で編集することはできません。むしろ、を使用する必要がありますcons_iterator
。
T* pData_;
クラスに内部ストレージがある場合、インターレーターは(の代わりに)そのポインターを持っている必要があります。T pData_;
その後、驚くほど正しいバージョンの準備ができているスターを削除する必要はありませんT &operator*()
;)ポイントは、incrementivgイテレーターがこのポインターとインクリメント値をインクリメントする必要があるということです関数内でポイントされadd1
た値をインクリメントする必要があります。これで、両方の操作が同じ変数をインクリメントするので、それらを取得します+=2
。
編集:
@DavidRodríguez-dribeas-許可されたシーケンシャルアクセス(どのシーケンス要素にアクセスできるか)の違いを説明するためのさまざまな入力イテレータカテゴリを検討していますが、説明されている問題は、Range
クラスインスタンスが設計定数によるものであるということです(少なくともイテレータのみを使用して変更できます)。ランダムアクセスカテゴリを与えることに反対するものは何も見えません。
唯一のオプションは、イテレータをconst_iteratorに置き換えることです。これにより、イテレータの値を変更できなくなります。これは、コンテナをいくつかのカテゴリに分割し、カテゴリごとに必要なISO C ++とは少し異なり、begin()
コンテナ自体が宣言されている場合にのみend()
返されます。ただし、(23.1.1によると)クラスがISOC++ビューのコンテナでさえあることはせいぜい議論の余地があると思います。const_iterator
const
Range
コンテナは、他のオブジェクトを格納するオブジェクトです。これらは、コンストラクタ、デストラクタ、挿入および消去操作を通じて、これらのオブジェクトの割り当てと割り当て解除を制御します。
Rangeクラスには、反復オブジェクトの実際のストレージがないようです。ここでは、私たちは野外に出ており、標準にそれほど準拠する必要はないと思います。
EDIT2:
まずconst iterator
、と同じではありませんconst_iterator
。最初のイテレータは変更できないイテレータであり(たとえば、増分された別の値を順番に指すため)、別のイテレータはそれを許可しますが、代わりにポイントされた値の変更を許可しないため、(*i)=3
失敗します。
第二に、これは私がそれをしたであろう方法です:
template <typename T>
class Range {
public:
class const_iterator;
typedef const_iterator iterator; //For stl-compliance - some algorythms use that.
IntegerRange(T low, T high) : low_(low), high_(high) { assert(low <= high);}
const_iterator begin() const { return const_iterator(low_); }
const_iterator end() const { return const_iterator(high_); }
private:
const T low_;
const T high_;
};
template<typename T>
class Range<T>::const_iterator : public std::iterator<std::forward_iterator_tag, T>
{
public:
// default constructor
const_iterator() : pData_(0)
{
}
// constructor from const T&
const_iterator(const T &pData) : pData_(pData)
{
}
// constructor from T&
const_iterator(T &pData) : pData_(pData)
{
}
// operator =
const_iterator &operator=(const const_iterator &other)
{
this->pData_ = other.pData_;
return *this;
}
// pre-increment operator
const_iterator & operator++()
{
++(this->pData_);
return *this;
}
// post-increment operator
const_iterator operator++(int)
{
const_iterator temp(*this);
this->operator++();
return temp;
}
// operator ==
bool operator==(const const_iterator &other) const
{
return this->pData_ == other.pData_;
}
// operator !=
bool operator!=(const iterator &other) const
{
return !operator==(other);
}
// operator* r-value
const T &operator*() const
{
return (this->pData_); // had to remove the *
}
// operator-> r-value
const T *operator->() const
{
return &(this->pData_);
}
private:
T pData_;
};
const_iterator仕様を維持する限り、const_iteratorの代わりに名前イテレータを維持する(またはクラス名としてqqwfmnghngを使用する)ことは明らかに自由です-この場合、指定された値を変更することを目的としているため、l値演算子を提供しません-何それは意味がありますか?