xmllmx
xmllmx

Reputation: 42255

Is operator->() guaranteed to be available for a standard C++ container's iterator?

#include <map>

int main()
{
    auto coll = std::map<int, int>{{1, 2}};
    auto pos  = coll.begin();

    (*pos).first;   // OK. Conforming to the C++ standard.
    pos->first;     // Does this conform to the C++ standard too?
}

According to cppref, an iterator object pos must guarantee *pos and ++pos are valid expressions. However, the C++ standard doesn't require that pos->first must also be a valid expression.

Is operator->() guaranteed to be available for a standard C++ container's iterator?

Upvotes: 1

Views: 116

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473407

The C++17 named iterator requirements for InputIterator, and therefore all derivations, does require that iterators provide operator->. However, the C++20 iterator concepts do not. Particular implementations may provide them, and the standard library containers follow the rules of both the C++17 requirements and C++20 concepts.

So if you have a template function that constrains itself against the C++20 iterator/range concepts, you are not allowed to use ->. Of course, if you're in non-template code and you know what types you're being given, you can use the full interface available to you.

Note that C++17's OutputIterator requirements do not include ->. So any standard library iterators that are pure OutputIterators (ostream_iterator, for example) does not necessarily provide it.

Upvotes: 2

mmackliet
mmackliet

Reputation: 272

If the standard says that iterator_traits::pointer and iterator_traits::reference are non-void types, than the standard guarantees that the iterator must have an operator->

23.3.2.3 Iterator traits [iterator.traits] 1 To implement algorithms only in terms of iterators, it is sometimes necessary to determine the iterator category that corresponds to a particular iterator type. Accordingly, it is required that if I is the type of an iterator, the type iterator_traits::iterator_category be defined as the iterator’s iterator category. In addition, the types iterator_traits::pointer iterator_traits::reference shall be defined as the iterator’s pointer and reference types; that is, for an iterator object a of class type, the same type as decltype(a.operator->()) and decltype(*a), respectively. The type iterator_- traits::pointer shall be void for an iterator of class type I that does not support operator->. Additionally, in the case of an output iterator, the types

Upvotes: 1

Related Questions