为什么reverse_iterator会双重定义其嵌套类型?

时间:2015-03-17 20:21:18

标签: c++ iterator language-lawyer reverse-iterator iterator-traits

迭代器适配器reverse_iterator似乎双重定义了大多数嵌套类型。特别是,它会从std::iterator公开继承,从而公开iterator_categoryvalue_typedifference_typepointerreference。除了iterator_categoryvalue_type之外,这些都在类定义中再次明确typedef

24.5.1.1 类模板reverse_iterator [reverse.iterator]

namespace std {
template <class Iterator>
class reverse_iterator : public
     iterator<typename iterator_traits<Iterator>::iterator_category,
     typename iterator_traits<Iterator>::value_type,
     typename iterator_traits<Iterator>::difference_type,
     typename iterator_traits<Iterator>::pointer,
     typename iterator_traits<Iterator>::reference> {
public:
  typedef Iterator                                            iterator_type;
  typedef typename iterator_traits<Iterator>::difference_type difference_type;
  typedef typename iterator_traits<Iterator>::reference       reference;
  typedef typename iterator_traits<Iterator>::pointer         pointer;
  // ... rest of the class
};

问题:为什么重复定义?这只是为了说明的目的,还是有更多的东西?为什么不重新定义iterator_categoryvalue_type

2 个答案:

答案 0 :(得分:7)

现在,他们已经不再使用std::iterator作为基类,只是指定每个迭代器必须定义正确的类型名称。

当他们在标准中指定基类时,它会限制实现以这种方式实现类,即使唯一真正的意图是指定迭代器需要定义一些名称。特别是,您可以is_base_of确定std::iterator是否为std::reverse_iterator的基类。不,没有什么是多态的,所以这样做非常愚蠢和毫无意义,但是如果你这样做,那么当前的标准说它必须返回true。

看起来(对我而言)这或多或少是一个意外的中途点,在(或多或少意外地)需要使用std::iterator作为基类的过程中,并且只是指定必须在std::reverse_iterator(以及其他各种迭代器)中定义的名称。

对于那些关心的人,其历史包括:

N3931
Issue 2438

还有关于弃用unary_function和binary_function的相关讨论文章:

N3145
N3198

提供这些的原因与std::iterator大致相同(即,只是为了在派生类中提供某些typedef),因此删除它们的原因与停止使用std::iterator非常相关。基类。

答案 1 :(得分:3)

这更像是一个猜测,但所有那些冗余的typedefs声明在reverse_iterator的类主体的规范中使用的类型。例如(C ++ 03 IS):

pointer operator->() const;
reference operator[](difference_type n) const;

由于iterator<..>是从属基类,因此不会搜索名称pointerreference。所以typedef这些名称使剩下的规范更简单:

typename iterator_traits<Iterator>::pointer operator->() const;
typename iterator_traits<Iterator>::reference operator[](typename iterator_traits<Iterator>::difference_type n) const;

另一方面,value_type没有出现在类体内,因此它不需要冗余的typedef