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

标签 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.

最佳答案

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

将此模板应用于 my_iteratorIterator,我也没有发现任何技术上的错误。这些模板的上述定义是直接从标准中提取的。因此,就 C++11 标准中这些模板的实际严格文字声明而言,我认为这些声明没有任何问题。

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

我粗略地看了一下,找不到任何明确声明使用 std::iteratorstd::iterator_traits 的五个预定义标签以外的任何东西> 是未定义的行为,因此仅在这个有限的示例中,我会说这在技术上是有效的,即使它的值(value)值得怀疑。

关于c++ - C++ 标准库是否禁止非标准迭代器类别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26900470/

相关文章:

c++ - 为什么我的代码会导致 "cannot instantiate abstract class"?

c++ - 小投入,大产出?

java - Java 迭代器的 2 种形式

curry 时的 Groovy 错误

c++ - 复制列表和关联的迭代器

c++ - STL std::sort() 使用 Introsort,但它是如何工作的?

c++ - Gnuplot 未正确读取 YYYY-mm-dd 并获取 "more % conversions than data arguments"(Xcode C++)

c++ - 没有模板参数列表就不能引用类模板

python - 在Python中将迭代器拆分为两个连续的迭代器

c++ - 迭代器的比较程度如何?