Alexey Starinsky
Alexey Starinsky

Reputation: 4339

Why is my iterator not std::input_iterator?

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>());

Upvotes: 1

Views: 555

Answers (1)

user17732522
user17732522

Reputation: 76819

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.

Upvotes: 3

Related Questions