If I have a user-defined class :
class MyColl {
int *data ;
public :
class Itr {
int operator*() {}
void operator ()
bool operator != (const Itr &oth)
} ;
Itr begin() {}
Itr end() {}
} ;
Can I use std::next
on objects of MyColl
If yes, then what needs to be done
CodePudding user response:
// How to implement a forward iterator for your collection class
template <typename T>
class MyCollection
{
public:
struct MyCollectionIterator
{
// These five typedefs tell other things about your iterator
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
explicit MyCollectionIterator( ... ) ... {}
// These five methods implement the minimum required behavior of a forward iterator
reference operator * () const {...}
iterator & operator () {...}
iterator operator (int) {...}
bool operator == ( iterator that ) {...}
bool operator != ( iterator that ) {...}
};
MyCollectionIterator begin() { return MyCollectionIterator(...); }
MyCollectionIterator end() { return MyCollectionIterator(...); }
};
There are other iterator types beyond a forward iterator. If possible, you should implement the most capable iterator type you can: if not random access, then bidirectional, and if not bidirectional, then forward.
Iterators have been an increasingly frightening thing to look at in C (see docs here), but the basic idea is simply a class that knows how to pretend to be a pointer sufficient to access your collection’s data. To do that it must provide certain kinds of information and capabilities.
That little table of iterator types in the linked docs will help you when adding the required functionality to your iterator class.
CodePudding user response:
Can I use std::next on user defined class
You can use std::next
with any class that is an iterator.
Can I use std::next on objects of MyColl
No, because MyColl
is not an iterator.
You also cannot use it with MyColl::Itr
, because that isn't an iterator either.
I am missing something because I am getting following error
error: no type named ‘difference_type’ in ‘struct std::iterator_traits<MyColl::Itr>
The error message tells you what you're missing. You're missing std::iterator_traits<MyColl::Itr>::difference_type
. Without it, MyColl::Itr
is not an iterator. More generally, the class must satisfy all requirements of the iterator
concept.
CodePudding user response:
I figured out that my Itr
class must define the following :
using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using pointer = value_type*;
using reference = value_type&;
If I must support the std::prev
function also then Itr
must define prefix operator-- and iterator_category
must be std::random_access_iterator_tag