iterator_traits的设计目的是什么?

What is the design purpose of iterator_traits?

C++ 标准库同时定义了 iteratoriterator_traits 模板。似乎一般来说,iterator_traits 只是提取在 iterator 中明确定义的属性。如果要使用iterator_traits,直接使用对应的iterator即可。如果需要特定类型的特化(例如 T*),则 iterator 的特化可以满足要求。这种间接的好处是什么?

It seemed that in general, the iterator_traits just extracts properties that defined explicitly in iterator. If a iterator_traits is to be used, one can use the corresponding iterator directly.

并非所有迭代器都可以键入别名作为成员。

What's the benefit this indirection?

让所有的迭代器有一个统一的接口。更具体地说,指针也是迭代器,作为 non-class 类型,指针不能有成员。

因此,例如,当迭代器的用户想要回答“an_iterator_type 指向的对象的类型是什么”这个问题时,他们不能使用 an_iterator_type::value_type,因为那不可能为所有迭代器定义 - 特别是指针。他们可以使用的是 std::iterator_traits<an_iterator_type>::value_type ,它可以为所有迭代器定义——包括指针。这就是 std::iterator_traits.

的目的

该标准定义了指针的 std::iterator_traits<T*> 特化。虽然可以,但您不需要为自定义迭代器类型定义特化,因为您可以将类型定义为成员,std::iterator_traits.

的通用定义将使用这些成员

std::iterator 的目的是可选地用作基础 class 以帮助定义自定义迭代器的成员类型。然而,它的使用从来都不是必需的,它被认为是一个有缺陷的设计,长期以来一直不鼓励使用它。自 C++17 起,它已被弃用,并可能从未来的标准中删除。

一个有望说明std::iterator设计问题的例子:

// using the deprecated std::iterator
struct iterator : std::iterator<
    std::input_iterator_tag,   // OK so far
    long,                      // can you guess what member this argument defines?
    long,                      // how about this?
    const long*,               // you can probably guess this one
    long>                      // still, no clue
{
    ...

// recommended way without using std::iterator
struct iterator
{
    using iterator_category = std::input_iterator_tag;
    using value_type = long;
    using difference_type = long;
    using pointer = const long*;
    using reference = long;
    ...