長年問題なく使用しているカスタム コンテナがあります。最近、コンテナーにイテレーターを定義すると、 で定義されたすべてのアルゴリズムを効果的に使用できることがわかりました<algorithm>
。それだけでなく、スラスト ライブラリ (基本的には Nvidia GPU 用の STL の CUDA バージョンと考えてください) はイテレータを多用しているようで、それらを使用することでそのライブラリも使用できるようになることを望んでいます。
とにかく、これは私自身のイテレータを書く最初の試みなので、私がここに持っているものを投稿して、さらなる支援を求め、私がやっていることは正しいことを確認しようと思いました. iterator
そこで、とクラスの両方をサポートする小さな配列クラスを作成しconst_iterator
ました。さまざまな STL アルゴリズムを使用してクラスを実行しましたが、すべて正常に動作しているように見えますが、必ずしもすべてが正しいとは限りません。特に、イテレータで見逃している演算子はありますか? 余分な不要なものを定義しましたか? また、 と のほとんどがiterator
似const_iterator
ているため、重複を防ぐ方法はありますか?
私は提案と改善を受け入れています:)
実際の例: http://ideone.com/7YdiQY
#include <cstddef>
#include <iostream>
#include <iterator>
#include <algorithm>
template<typename T>
class my_array{
T* data_;
std::size_t size_;
public:
// ---------------------------------
// Forward declaration
// ---------------------------------
class const_iterator;
// ---------------------------------
// iterator class
// ---------------------------------
class iterator: public std::iterator<std::random_access_iterator_tag, T>
{
public:
iterator(): p_(NULL) {}
iterator(T* p): p_(p) {}
iterator(const iterator& other): p_(other.p_) {}
const iterator& operator=(const iterator& other) {p_ = other.p_; return other;}
iterator& operator++() {p_++; return *this;} // prefix++
iterator operator++(int) {iterator tmp(*this); ++(*this); return tmp;} // postfix++
iterator& operator--() {p_--; return *this;} // prefix--
iterator operator--(int) {iterator tmp(*this); --(*this); return tmp;} // postfix--
void operator+=(const std::size_t& n) {p_ += n;}
void operator+=(const iterator& other) {p_ += other.p_;}
iterator operator+ (const std::size_t& n) {iterator tmp(*this); tmp += n; return tmp;}
iterator operator+ (const iterator& other) {iterator tmp(*this); tmp += other; return tmp;}
void operator-=(const std::size_t& n) {p_ -= n;}
void operator-=(const iterator& other) {p_ -= other.p_;}
iterator operator- (const std::size_t& n) {iterator tmp(*this); tmp -= n; return tmp;}
std::size_t operator- (const iterator& other) {return p_ - other.p_;}
bool operator< (const iterator& other) {return (p_-other.p_)< 0;}
bool operator<=(const iterator& other) {return (p_-other.p_)<=0;}
bool operator> (const iterator& other) {return (p_-other.p_)> 0;}
bool operator>=(const iterator& other) {return (p_-other.p_)>=0;}
bool operator==(const iterator& other) {return p_ == other.p_; }
bool operator!=(const iterator& other) {return p_ != other.p_; }
T& operator[](const int& n) {return *(p_+n);}
T& operator*() {return *p_;}
T* operator->(){return p_;}
private:
T* p_;
friend class const_iterator;
};
// ---------------------------------
// const_iterator class
// ---------------------------------
class const_iterator: public std::iterator<std::random_access_iterator_tag, T>
{
public:
const_iterator(): p_(NULL) {}
const_iterator(const T* p): p_(p) {}
const_iterator(const iterator& other): p_(other.p_) {}
const_iterator(const const_iterator& other): p_(other.p_) {}
const const_iterator& operator=(const const_iterator& other) {p_ = other.p_; return other;}
const const_iterator& operator=(const iterator& other) {p_ = other.p_; return other;}
const_iterator& operator++() {p_++; return *this;} // prefix++
const_iterator operator++(int) {const_iterator tmp(*this); ++(*this); return tmp;} // postfix++
const_iterator& operator--() {p_--; return *this;} // prefix--
const_iterator operator--(int) {const_iterator tmp(*this); --(*this); return tmp;} // postfix--
void operator+=(const std::size_t& n) {p_ += n;}
void operator+=(const const_iterator& other) {p_ += other.p_;}
const_iterator operator+ (const std::size_t& n) const {const_iterator tmp(*this); tmp += n; return tmp;}
const_iterator operator+ (const const_iterator& other) const {const_iterator tmp(*this); tmp += other; return tmp;}
void operator-=(const std::size_t& n) {p_ -= n;}
void operator-=(const const_iterator& other) {p_ -= other.p_;}
const_iterator operator- (const std::size_t& n) const {const_iterator tmp(*this); tmp -= n; return tmp;}
std::size_t operator- (const const_iterator& other) const {return p_ - other.p_;}
bool operator< (const const_iterator& other) const {return (p_-other.p_)< 0;}
bool operator<=(const const_iterator& other) const {return (p_-other.p_)<=0;}
bool operator> (const const_iterator& other) const {return (p_-other.p_)> 0;}
bool operator>=(const const_iterator& other) const {return (p_-other.p_)>=0;}
bool operator==(const const_iterator& other) const {return p_ == other.p_; }
bool operator!=(const const_iterator& other) const {return p_ != other.p_; }
const T& operator[](const int& n) const {return *(p_+n);}
const T& operator*() const {return *p_;}
const T* operator->() const {return p_;}
private:
const T* p_;
};
my_array()
: data_(NULL), size_(0)
{}
my_array(std::size_t size)
: data_(new T[size]), size_(size)
{}
my_array(const my_array<T>& other){
size_ = other.size_;
data_ = new T[size_];
for (std::size_t i = 0; i<size_; i++)
data_[i] = other.data_[i];
}
my_array(const const_iterator& first, const const_iterator& last){
size_ = last - first;
data_ = new T[size_];
for (std::size_t i = 0; i<size_; i++)
data_[i] = first[i];
}
~my_array(){
delete [] data_;
}
const my_array<T>& operator=(const my_array<T>& other){
size_ = other.size_;
data_ = new T[size_];
for (std::size_t i = 0; i<size_; i++)
data_[i] = other.data_[i];
return other;
}
const T& operator[](std::size_t idx) const {return data_[idx];}
T& operator[](std::size_t& idx) {return data_[idx];}
std::size_t size(){return size_;}
iterator begin(){ return iterator(data_); }
iterator end() { return iterator(data_+size_); }
const_iterator begin() const{ return const_iterator(data_); }
const_iterator end() const { return const_iterator(data_+size_);}
};
template<typename T>
void print(T t) {
std::cout << t << std::endl;
}
int main(){
// works!
int list [] = {1, 3, 5, 2, 4, 3, 5, 10, 10};
my_array<int> a(list, list+sizeof(list)/sizeof(int));
// works!
for (my_array<int>::const_iterator it = a.begin(), end = a.end();
it != end; ++it)
std::cout << ' ' << *it;
std::cout << std::endl;
// works!
std::for_each(a.begin(), a.end(), print<int>);
std::cout << std::endl;
// works!
my_array<int> b(a.size());
std::copy(a.begin(), a.end(), b.begin());
// works!
my_array<int>::iterator end = std::remove(a.begin(), a.end(), 5);
std::for_each(a.begin(), end, print<int>);
std::cout << std::endl;
// works!
std::random_shuffle(a.begin(), end);
std::for_each(a.begin(), end, print<int>);
std::cout << std::endl;
// works!
std::cout << "Counts of 3 in array = " << std::count(a.begin(), end, 3) << std::endl << std::endl;
// works!
std::sort(a.begin(), end);
std::for_each(a.begin(), end, print<int>);
std::cout << std::endl;
// works!
if (!std::binary_search(a.begin(), a.end(), 5))
std::cout << "Removed!" << std::endl;
return 0;
}