如何避免为模板化迭代器的每个可能的实例化专门化iterator_traits?
How to avoid specializing iterator_traits for each possible instantiation of a templated iterator?
我想增加我的远程基于for循环,例如通过启用反向iteraton。我设法通过编写适配器使其在某种程度上工作,但我迷失了如何使adpaptor可组合。
#include <iostream>
template <typename IT> struct reversed_range {
struct reversed_iterator {
IT it;
reversed_iterator(IT it): it(it){}
reversed_iterator& operator++(){
--it;
return (*this);
}
typename std::iterator_traits<IT>::reference operator*(){
IT tmp = it;
--tmp;
return *tmp;
}
bool operator==(const reversed_iterator& other) const {
return it == other.it;
}
bool operator!=(const reversed_iterator& other) const {
return !(*this == other);
}
};
IT itbegin;
IT itend;
reversed_range(const IT& b,const IT& e): itbegin(b),itend(e){}
reversed_iterator begin() const { return reversed_iterator(itend); }
reversed_iterator end() const { return reversed_iterator(itbegin); }
};
template <typename IT>
reversed_range<IT> reverse_range(const IT& begin,const IT& end) {
return reversed_range<IT>(begin,end);
}
template <typename C>
reversed_range<C> reverse_range(const C& c) {
return reversed_range<typename C::iterator>(std::begin(c),std::end(c));
}
int main() {
int x[] = {1,2,3,4,5};
for (auto y : reverse_range(std::begin(x),std::end(x))){
std::cout << y << "t";
}
for (auto y : reverse_range(reverse_range(std::begin(x),std::end(x)))){
std::cout << y << "t";
}
return 0;
}
第一个循环就像一个魅力,但对于第二个循环,我得到错误:
error: no type named ‘reference’ in ‘struct std::iterator_traits<reversed_range<int*> >’
typename std::iterator_traits<IT>::reference operator*(){
^~~~~~~~
我知道为什么会发生这种情况,我知道如何针对这种特殊情况解决它。但是,如果我正确理解这个答案,我将不得不针对我的reversed_iterator
的每个可能的实例化专门化iterator_traits
,这并不可行。我有点迷茫,大多数时候我写自己的迭代器,我发现自己写了很多样板,只是为了达到一个点,我意识到我需要成倍增加的样板才能让它工作。我的意思是我什至没有开始考虑const_iterator
。
有没有办法让上述工作(必须为我想逆转的每个iterator
专门化iterator_traits
?
PS:标记为C++11,因为这是我目前的范围,但如果在这方面有改进,我不介意使用更新的标准。
默认情况下std::iterator_traits<Iterator>::something
只是Iterator::something
。因此,只需将 typedefs 添加到您的reversed_iterator
类型中:
struct reversed_iterator {
using difference_type = typename std::iterator_traits<IT>::difference_type;
using value_type = typename std::iterator_traits<IT>::value_type;
using pointer = typename std::iterator_traits<IT>::pointer;
using reference = typename std::iterator_traits<IT>::reference;
using iterator_category = /* appropriate category */;
// ...
};
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 如何避免为模板化迭代器的每个可能的实例化专门化iterator_traits?
- 模板专门化的隐式实例化
- c++模板函数:显式实例化一个或多个专门化
- 专门化后的显式实例化
- 实例化后的显式专门化
- 即使具有显式实例化,也不会为显式专门化模板生成代码
- 如何防止非专门化模板实例化