C ++标准库是否禁止非标准迭代器类别?

时间:2014-11-13 02:43:22

标签: c++ iterator

以下用于创建用户定义的迭代器类别标记的程序被clang(使用-stdlib=libc++)拒绝,但不被其他编译器和标准库实现拒绝:

#include <iterator>

struct my_iterator_tag {};

struct my_iterator : std::iterator<my_iterator_tag, int> {};

int main()
{
  std::iterator_traits<my_iterator>::value_type x;
  return 0;
}

我不清楚C ++标准是否禁止使用具有非标准迭代器类别的迭代器类型实例化std::iterator_traits

这个程序是非法的吗?

clang的输出(使用libc ++时)如下:

$ clang -stdlib=libc++ test.cpp 
test.cpp:9:38: error: no type named 'value_type' in 'std::__1::iterator_traits<my_iterator>'
  std::iterator_traits<my_iterator>::value_type x;
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
1 error generated.

1 个答案:

答案 0 :(得分:2)

std::iterator模板定义如下:

template<class Category, class T, class Distance = ptrdiff_t,
    class Pointer = T*, class Reference = T&> struct iterator {
    typedef T value_type;
    typedef Distance difference_type;
    typedef Pointer pointer;
    typedef Reference reference;
    typedef Category iterator_category;
  };
}

我认为您的声明没有任何问题:

struct my_iterator : std::iterator<my_iterator_tag, int> {};

所以,松散地说,你最终定义:

struct my_iterator {

    // ...

    typedef Category my_iterator_tag;

    // ...
};

看不出有什么问题。这是一个有效的声明。

现在,让我们来看看iterator_traits

的定义
template<class Iterator> struct iterator_traits {
   typedef typename Iterator::difference_type difference_type;
   typedef typename Iterator::value_type value_type;
   typedef typename Iterator::pointer pointer;
   typedef typename Iterator::reference reference;
   typedef typename Iterator::iterator_category iterator_category;
};

将此模板应用于Iterator my_iterator,我在这里看不到任何技术上的错误。这些模板的上述定义直接从标准中解除。因此,对于C ++ 11标准中这些模板的实际严格,文字声明,我认为声明没有错。

当然,C ++标准定义了五个标准迭代器类别,因此就C ++库的其余部分而言,有必要进一步分析它。我认为像迭代器适配器这样的各种东西可能是未定义的行为,除了五个标准迭代器类别之外还有其他任何东西。

粗略地说,我找不到任何明确说明使用除了std::iteratorstd::iterator_traits的五个预定义标签之外的任何内容都是未定义的行为的东西,所以仅在这个有限的示例中,我认为这在技术上是有效的,即使它具有可疑价值。