On March 21st the standards committee voted to approve the deprecation of std::iterator
proposed in P0174:
The long sequence of void arguments is much less clear to the reader than simply providing the expected
typedef
s in the class definition itself, which is the approach taken by the current working draft, following the pattern set in c++14
Before c++17 inheritance from std::iterator
was encouraged to remove the tedium from iterator boilerplate implementation. But the deprecation will require one of these things:
typedef
sauto
rather than depending upon the iterator to declare typesstd::iterator_traits
may be updated to work without inheriting from std::iterator
Can someone enlighten me on which of these options I should expect, as I design custom iterators with an eye towards c++17 compatibility?
The discussed alternatives are clear but I feel that a code example is needed.
Given that there will not be a language substitute and without relying on boost or on your own version of iterator base class, the following code that uses std::iterator
will be fixed to the code underneath.
std::iterator
template<long FROM, long TO>
class Range {
public:
// member typedefs provided through inheriting from std::iterator
class iterator: public std::iterator<
std::forward_iterator_tag, // iterator_category
long, // value_type
long, // difference_type
const long*, // pointer
const long& // reference
>{
long num = FROM;
public:
iterator(long _num = 0) : num(_num) {}
iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
bool operator==(iterator other) const {return num == other.num;}
bool operator!=(iterator other) const {return !(*this == other);}
long operator*() {return num;}
};
iterator begin() {return FROM;}
iterator end() {return TO >= FROM? TO+1 : TO-1;}
};
(Code from http://en.cppreference.com/w/cpp/iterator/iterator with original author's permission).
std::iterator
template<long FROM, long TO>
class Range {
public:
class iterator {
long num = FROM;
public:
iterator(long _num = 0) : num(_num) {}
iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
bool operator==(iterator other) const {return num == other.num;}
bool operator!=(iterator other) const {return !(*this == other);}
long operator*() {return num;}
// iterator traits
using difference_type = long;
using value_type = long;
using pointer = const long*;
using reference = const long&;
using iterator_category = std::forward_iterator_tag;
};
iterator begin() {return FROM;}
iterator end() {return TO >= FROM? TO+1 : TO-1;}
};