I wrote a custom iterator named Text_Iterator for a simple text editor. However, STL algorithms such as find() would not recognize it as a legitimate iterator.
My code is:
using Line = std::vector<char>;
class Text_iterator {
std::list<Line>::iterator ln;
Line::iterator pos;
public:
Text_iterator(std::list<Line>::iterator ll, Line::iterator pp)
: ln{ll}, pos{pp} {}
char& operator*() { return *pos; }
Text_iterator& operator++();
Text_iterator& operator--();
bool operator==(const Text_iterator& other) const
{
return (ln == other.ln && pos == other.pos);
}
bool operator!=(const Text_iterator& other) const
{
return (!(*this == other));
}
};
When I try to use this iterator in an algorithm, for example in find(), I get the following error:
1>...\xutility(861,56): error C2794: 'value_type': is not a member of any direct or indirect base class of 'std::iterator_traits<_InIt>'
1> with
1> [
1> _InIt=Text_iterator
1> ]
Why would it not register as a legitimate iterator?
Edit: Works with the following additional declarations:
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = char;
using pointer = char*;
using reference = char&;
The error message is complaining that std::iterator_traits
does not have a value_type
member when applied to your Text_iterator
class.
Your class's operator*
is returning a char&
, but your class does not have a value_type
member that aliases char
, eg:
class Text_iterator {
...
public:
typedef char value_type;
// or: using value_type = char;
// or: typedef std::iterator_traits<Line::iterator>::value_type value_type;
// or: using value_type = st::iterator_traits<Line::iterator>::value_type;
...
};
std::find()
only works with iterators that satisfy the requirements of InputIterator or ForwardIterator.
So, you need to either
value_type
) so the default std::iterator_traits
can find them.std::iterator_traits
for your class.