如何检查传递的Iterator是一个随机访问迭代器?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何检查传递的Iterator是一个随机访问迭代器?相关的知识,希望对你有一定的参考价值。
我有以下代码,它执行一些迭代器算术:
template<class Iterator>
void Foo(Iterator first, Iterator last) {
typedef typename Iterator::value_type Value;
std::vector<Value> vec;
vec.resize(last - first);
// ...
}
(last - first)
表达式(AFAIK)仅适用于随机访问迭代器(如vector
和deque
中的那些)。如何检查传递的迭代器满足此要求的代码?
答案
如果Iterator
是一个随机访问迭代器,那么
std::iterator_traits<Iterator>::iterator_category
将是std::random_access_iterator_tag
。实现这个的最简洁方法可能是创建第二个函数模板并让Foo
调用它:
template <typename Iterator>
void FooImpl(Iterator first, Iterator last, std::random_access_iterator_tag) {
// ...
}
template <typename Iterator>
void Foo(Iterator first, Iterator last) {
typedef typename std::iterator_traits<Iterator>::iterator_category category;
return FooImpl(first, last, category());
}
这样做的好处是,如果您愿意,可以为不同类别的迭代器重载FooImpl
。
Scott Meyers在一本有效的C ++书籍中讨论了这种技术(我不记得哪一本)。
另一答案
除了标签发送,您还可以使用std::random_access_iterator_tag
直接将该类别与std::is_same_v
进行比较:
using category = typename std::iterator_traits<Iterator>::iterator_category;
if constexpr (std::is_same_v<category, std::random_access_iterator_tag>) {
vec.resize(last - first);
}
这有时会导致更清晰简洁的代码,特别是如果实现的一小部分(如保留向量大小)取决于迭代器类别。
以上是关于如何检查传递的Iterator是一个随机访问迭代器?的主要内容,如果未能解决你的问题,请参考以下文章