我有以下代码,它执行一些迭代器算术:
template<class Iterator>
void Foo(Iterator first, Iterator last) {
typedef typename Iterator::value_type Value;
std::vector<Value> vec;
vec.resize(last - first);
// ...
}
Run Code Online (Sandbox Code Playgroud)
该(last - first)表达的作品(据我所知)仅适用于随机访问迭代器(像的那些vector和deque).如何检查传递的迭代器满足此要求的代码?
Jam*_*lis 33
如果Iterator是随机访问迭代器,那么
std::iterator_traits<Iterator>::iterator_category
Run Code Online (Sandbox Code Playgroud)
会的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());
}
Run Code Online (Sandbox Code Playgroud)
这样做的好处是FooImpl,如果您愿意,可以为不同类别的迭代器重载.
Scott Meyers在一本有效的C++书籍中讨论了这种技术(我不记得哪一本).
vit*_*aut 13
除了标签调度之外,您还可以将类别与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);
}
Run Code Online (Sandbox Code Playgroud)
这有时会产生更清晰简洁的代码,特别是当您的实现中只有一小部分(例如保留向量大小)依赖于迭代器类别时。
| 归档时间: |
|
| 查看次数: |
6210 次 |
| 最近记录: |