std::input_iterator_tag, std::output_iterator_tag, std::forward_iterator_tag, std::bidirectional_iterator_tag, std::random_access_iterator_tag, std::contiguous_iterator_tag
在标头 <iterator> 定义 | ||
struct input_iterator_tag {}; | (1) | |
struct output_iterator_tag {}; | (2) | |
struct forward_iterator_tag : public input_iterator_tag {}; | (3) | |
struct bidirectional_iterator_tag : public forward_iterator_tag {}; | (4) | |
struct random_access_iterator_tag : public bidirectional_iterator_tag {}; | (5) | |
struct contiguous_iterator_tag : public random_access_iterator_tag {}; | (6) | (C++20 起) |
定义迭代器的分类。每个标签均为空类型。
迭代器类别
对于每个老式迭代器 (LegacyIterator) 类型 It
,typedef
std::iterator_traits<It>::iterator_category 必须定义为这些标签类型之一的别名,以指示 It
所在的最特定的类别。
input_iterator_tag
对应老式输入迭代器 (LegacyInputIterator) 。output_iterator_tag
对应老式输出迭代器 (LegacyOutputIterator) 。forward_iterator_tag
对应老式向前迭代器 (LegacyForwardIterator) 。bidirectional_iterator_tag
对应老式双向迭代器 (LegacyBidirectionalIterator) 。random_access_iterator_tag
对应老式随机访问迭代器 (LegacyRandomAccessIterator) 。
迭代器分类标签携带信息,可以用于根据这一分类所蕴含的特定要求集合选择最高效算法。
迭代器概念对每个
若未提供 任何情况下,若不支持要求的操作则不满足各个概念,无关乎标签。 | (C++20 起) |
注解
没有用于老式连续迭代器 (LegacyContiguousIterator) 的独立标签。即不可能基于其 iterator_category
分辨老式连续迭代器 (LegacyContiguousIterator) 。要定义用于连续迭代器的特化算法,须使用 contiguous_iterator
概念。(C++20 起)
output_iterator_tag
和 output_iterator
概念之间没有对应关系。将 iterator_concept
设为 output_iterator_tag
只表明该类型并不实现 input_iterator
。
示例
如果需要根据迭代器分类标签选择算法,常用做法是使用分发函数(也可以通过 std::enable_if 实现)。各迭代器标签类也用于在相应的概念定义中表示要求,它们无法单独基于使用模式予以表达。(C++20 起)
#include <iostream> #include <iterator> #include <list> #include <vector> // 使用概念(标签检查是概念自身的一部分) template<std::bidirectional_iterator BDIter> void alg(BDIter, BDIter) { std::cout << "1. alg() \t 为双向迭代器调用\n"; } template<std::random_access_iterator RAIter> void alg(RAIter, RAIter) { std::cout << "2. alg() \t 为随机访问迭代器调用\n"; } // 遗留,使用标签派发 namespace legacy { // 经常把实现细节隐藏于专门的命名空间 namespace implementation_details { template<class BDIter> void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "3. legacy::alg() 为双向迭代器调用\n"; } template<class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "4. legacy::alg() 为随机访问迭代器调用\n"; } } // namespace implementation_details template<class Iter> void alg(Iter first, Iter last) { implementation_details::alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } } // namespace legacy int main() { std::list<int> l; alg(l.begin(), l.end()); // 1. legacy::alg(l.begin(), l.end()); // 3. std::vector<int> v; alg(v.begin(), v.end()); // 2. legacy::alg(v.begin(), v.end()); // 4. // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // 编译错误:没有匹配的函数可以调用 // legacy::alg(i1, i2); // 编译错误:没有匹配的函数可以调用 }
输出:
1. alg() 为双向迭代器调用 3. legacy::alg() 为双向迭代器调用 2. alg() 为随机访问迭代器调用 4. legacy::alg() 为随机访问迭代器调用
参阅
(C++17 弃用) | 简化简单的迭代器的必要类型定义的基类 (类模板) |
为迭代器各项性质提供统一接口 (类模板) |