I am working on some iterator type that needs to wrap another iterator. For some reason, the custom iterator is not well defined. For example, it does not compile when used with std::all_of, complaining about a mismatching function call to std::iterator_category:
/opt/.../stl_algo.h:108:32: error: no matching function for call to '__iterator_category(Iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >&)'
108 | std::__iterator_category(__first));
The custom iterator exposes a public iterator_category type, so I am not sure what the problem is here. To demonstrate the issue, the custom iterator simply wraps some other iterator type:
#include <functional>
#include <iterator>
#include <vector>
template<typename It>
struct Iterator
{
using difference_type = typename std::iterator_traits<It>::difference_type;
using value_type = typename std::iterator_traits<It>::value_type;
using pointer = value_type*;
using reference_type = value_type&;
using iterator_category = std::input_iterator_tag;
Iterator(It it) : it_{it} {}
friend bool operator==(const Iterator& x, const Iterator& y) { return x.it_ == y.it_; }
friend bool operator!=(const Iterator& x, const Iterator& y) { return !(x == y); }
Iterator& operator++()
{
++it_;
return *this;
}
Iterator operator++(int)
{
Iterator it{*this};
this->operator++();
return it;
}
reference_type operator*() { return *it_; }
private:
It it_;
};
int main()
{
std::vector<int> v{1, 2, 3};
auto first{Iterator{v.begin()}};
auto last{Iterator{v.end()}};
std::all_of(first, last, [](auto) { return true; });
}
The compiler errors are solved in case the iterator derives from std::iterator:
struct Iterator : public std::iterator<std::input_iterator_tag, typename It::value_type>
(see: https://godbolt.org/z/vMfj38)
So std::iterator brings something to the table that is missing from the definition of Iterator above, but what?