#include #include #include #include using namespace std; template class NumberIterTraits; template<> class NumberIterTraits { public: static int next(const vector &numbers, size_t sequence) { throw logic_error("NumberIterTraits::next should not be used."); } }; class Traits_Normal; template<> class NumberIterTraits { public: static int next(const vector &numbers, size_t sequence) { return numbers[sequence]; } }; class Traits_Cumulative; template<> class NumberIterTraits { public: static int next(const vector &numbers, size_t sequence) { if (sequence < 0) return 0; int value = 0; for (int i=0; i <= sequence; i++) value += numbers[i]; return value; } }; template > class NumberIter: public std::iterator< std::forward_iterator_tag, string > { public: // Constructors NumberIter(const vector &numbers, size_t seq) : sequence_(seq), numbers_(numbers) {} // Copy constructor NumberIter(const NumberIter &other) { numbers_ = other.numbers_; sequence_ = other.sequence_; } // Operators const int operator*() const { return Traits::next(numbers_, sequence_); } NumberIter & operator++(int) { sequence_++; return *this; } /* NumberIter operator=(NumberIter val) { numbers_ = val.numbers_; sequence_ = val.sequence_; return *this; } */ template bool operator==(const NumberIter& other) { return sequence_ == other.sequence_; } template bool operator!=(const NumberIter& other) { return !((*this) == other); } private: vector numbers_; size_t sequence_; friend class NumberIter; friend class NumberIter; }; class NumberRange { public: NumberRange(int rangebegin, int rangeend) { cout << "Constructing NumberRange object with numbers " << rangebegin << " to " << rangeend << endl; for (int i=rangebegin; i<=rangeend; i++) numbers_.push_back(i); } NumberIter begin() { NumberIter tmp(numbers_, 0); return tmp; } NumberIter end() { NumberIter tmp(numbers_, numbers_.size()); return tmp; } typedef NumberIter iterator; typedef NumberIter cumulative_iterator; private: vector numbers_; }; /** * ksh$ g++ iterators.cpp &&./a.out * Constructing NumberRange object with numbers 1 to 10 * NumberRange::iterator: * 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * NumberRange::cumulative_iterator: * 1 * 3 * 6 * 10 * 15 * 21 * 28 * 36 * 45 * 55 */ int main(int argc, char **argv) { NumberRange range(1, 10); cout << "NumberRange::iterator:" << endl; for (NumberRange::iterator iter = range.begin(); iter != range.end(); iter++) cout << *iter << endl; cout << "NumberRange::cumulative_iterator:" << endl; for (NumberRange::cumulative_iterator iter = range.begin(); iter != range.end(); iter++) cout << *iter << endl; return EXIT_SUCCESS; }