Why doesn't the iterator below satisfy std::input_iterator
concept? What did I miss?
template <class T>
struct IteratorSentinel {};
template <class T>
class Iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
Iterator() = default;
Iterator(const Iterator&) = delete;
Iterator& operator = (const Iterator&) = delete;
Iterator(Iterator&& other) = default;
Iterator& operator = (Iterator&& other) = default;
T* operator-> ();
T& operator* ();
bool operator== (const IteratorSentinel<T>&) const noexcept;
Iterator& operator ();
void operator (int);
};
The following static assertion fails:
static_assert(std::input_iterator<Iterator<int>>);
And, for example, the code below does not compile:
template <class T>
auto make_range()
{
return std::ranges::subrange(Iterator<T>(), IteratorSentinel<T>{});
}
std::ranges::equal(make_range<int>(), std::vector<int>());
CodePudding user response:
Your operator*
is not const
-qualified.
The std::input_iterator
concept (through the std::indirectly_readable
concept) requires that *
can be applied to both const
and non-const
lvalues as well as rvalues of the type and that in all cases the same type is returned.