Переключение между прямой и обратной итерацией

#c #list #iterator #reverse

#c #Список #итератор #обратный

Вопрос:

У меня есть класс анимации, который хранит кадры в std::list, в файле заголовка объявляется итератор, я увеличиваю итератор, используя время. Мои анимации работают нормально, пока я не попытаюсь отменить анимацию (из текущей позиции), я не могу уменьшить итератор (двунаправленный, да?). Я тоже думал о сохранении обратного итератора, но не могу найти хороший способ переключения между ними.

Как я могу плавно переключаться между прямой итерацией и обратной итерацией (не начиная с начала std::list).

Комментарии:

1. Рассматривали ли вы возможность использования std::vector вместо этого? Списки полезны, если у вас много вставок и удалений повсюду, но с анимацией, я не думаю, что это будет так.

2. Невозможно ответить без какого-либо примера кода относительно того, что не работает. std::list итераторы являются двунаправленными и -- работают с ними.

3. Изначально я использовал вектор, но изменил его на list, чтобы посмотреть, решит ли это мою проблему (потому что итератор предположительно двунаправленный).

4. vector и list оба имеют двунаправленные итераторы, и их уменьшение должно сработать. Как выглядит ваш код и какую ошибку вы получаете?

5. Опубликуйте соответствующий фрагмент кода и ошибку, которую вы получите. list<T>::iterator является двунаправленным. Перемещаете ли вы итератор в пределах границ списка?

Ответ №1:

Вы должны иметь возможность уменьшать итератор списка; не видя ваш код и ошибку, которую он выдает, я не могу догадаться, что там происходит не так.

Однако, возможно, было бы удобнее представить анимацию в виде общего диапазона итераторов:

 template <typename ForwardIterator>
void animate(ForwardIterator start, ForwardIterator end)
{
    for (; start != end;   start) {
        start->display();
    }
}

std::vector<frame> animation = ...;
animate(animation.begin(), animation.end());   // play forwards
animate(animation.rbegin(), animation.rend()); // play backwards
  

Ответ №2:

Что вы имеете в виду «я не могу уменьшить итератор»?

На моем Visual C 2010 это работает:

 std::list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);

auto i = l.end();
while (i != l.begin()) {
    --i;
    std::cout << *i << std::endl;
}