Я хочу увеличить свой диапазон на основе циклов, например, включив обратную итерацию.Мне удалось заставить его работать до некоторой степени, написав адаптер, но я заблудился о том, как сделать компоновщик 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*(){
^~~~~~~~
Я знаю, почему это происходит, и я знаю, как я мог это исправить для этогочастный случай.Однако, если я правильно понимаю этот ответ , мне придется специализироваться iterator_traits
для каждого возможного создания экземпляра моего reversed_iterator
, что на самом деле неосуществимо.Я немного растерялся, большую часть времени я пишу свои собственные итераторы, я обнаруживаю, что пишу много шаблонов, просто чтобы достичь точки, когда я понимаю, что мне понадобится экспоненциально больше шаблонов, чтобы это заработало.Я имею в виду, что я даже не начал рассматривать const_iterator
s.
Есть ли способ заставить работать выше (без необходимости специализировать iterator_traits
для каждого iterator
, который я когда-либо хочу повернуть вспять?
PS: помечен как C ++ 11, потому что это моя текущая область применения, но если есть улучшения в этом отношении, я не против использовать более новый стандарт.