operator->() 是否保证可用于标准 C++ 容器的迭代器?

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?
}

根据 cppref,迭代器对象 pos 必须保证 *pos++pos 是有效的表达式。但是,C++ 标准不要求 pos->first 也必须是有效表达式。

是否 operator->() 保证可用于标准 C++ 容器的迭代器?

如果标准说 iterator_traits::pointer 和 iterator_traits::reference 是非空类型,那么标准保证迭代器必须有一个 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

InputIterator 的 C++17 命名迭代器要求,因此所有派生,确实要求迭代器提供 operator->。但是,C++20 迭代器 概念 没有。特定的实现可能会提供它们,标准库容器遵循 C++17 要求和 C++20 概念的规则。

因此,如果您有一个模板函数,其自身受限于 C++20 iterator/range 概念,则不允许您使用 ->。当然,如果您使用的是非模板代码并且您知道给定的类型是什么,则可以使用可用的完整界面。

请注意,C++17 的 OutputIterator 要求包括->。因此,任何纯 OutputIterators 的标准库迭代器(例如 ostream_iterator)不一定提供它。