C++标准库是否禁止非标准迭代器类别
Does the C++ Standard Library prohibit non-standard iterator categories?
以下创建用户定义的迭代器类别标记的程序被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_iterator
Iterator
,我在这里也没有看到任何技术错误。这些模板的上述定义直接从标准中移除。因此,就 C++11 标准中这些模板的实际严格字面声明而言,我认为声明没有任何问题。
当然,C++标准定义了五个标准迭代器类别,因此就C++库的其余部分而言,有必要进一步分析。我想像迭代器适配器这样的各种东西可能是未定义的行为,除了五个标准迭代器类别之外的任何内容。
粗略地看一下,我找不到任何明确指出使用五个预定义标签以外的任何内容std::iterator
和std::iterator_traits
是未定义的行为,因此仅在这个有限的示例中,我会说这在技术上是有效的,即使它具有可疑的价值。
相关文章:
- 是否应避免从非常量迭代器转换为常量迭代器?
- 为什么我们在C++标准中没有"const 迭代器",而是const_iterator?
- 对于C字符串,是否有一个标准的C++迭代器
- 如何在单个模板调用中传递const_iterator和非const迭代器
- 使用 declval 获取非常量迭代器
- 标准上的 OMP 和并行操作::set<...>::迭代器
- 迭代器的标准接口::operator*返回的比T&和std::p air更多
- 将字符串::迭代器转换为标准::字符串
- 将迭代器放置为临时范围时,非销钉 - 操作和错误
- 为什么标准容器迭代器不会重载"->*"?
- 为什么反向迭代器不是 C++17 标准下的正式迭代器类别?
- 如何使用标准迭代器使用`boost :: range`迭代器
- C++迭代器"for loop"习惯用法,其步长> 1 并允许非随机访问反向迭代器
- 如何计算标准::矢量::<int>迭代器和标准::矢量<int>::reverse_iterator之间的距离?
- 具有子类容器的子类的非标准迭代器
- C++标准库是否禁止非标准迭代器类别
- 为什么c++共享指针的行为不像迭代器的标准指针
- 迭代器中的非标准语法错误?(c++)
- 擦除会const_iterator但使用迭代器(非常量)调用
- 我可以在非标准容器上使用迭代器库的访问函数吗?