Search code examples
c++iteratorstandardslanguage-design

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?


Solution

  • 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.