Зачем нам нужен своп в обратной реализации STL? Ускоренный C ++ (вопрос 8.4)

Я пытаюсь ответить на вопрос:
Почему мы называем своп, а не обмениваем значения *first а также *last в реализации обратной функции? Вот обратная функция:

template <class BiDirectionalIterator>
void reverse(BiDirectionalIterator first, BiDirectionalIterator last)
{
while(first < last) {
--last;
if(first != last) {
swap(*first++, *last);
}
}
}

Я пытаюсь прояснить свое понимание здесь. Я пытался обменять *first а также *last непосредственно:

template <class Bi>
void incorrect_reverse(Bi first, Bi last)
{
while(first < last) {
--last;
if(first != last) {
//here tmp and first both point to the same thing
Bi tmp = first;
*first = *last;
*last = *tmp;
first++;
}
}
}

Я видел, что это не сработало. Потом я попробовал Bi tmp = *first чтобы получить значение из first но получите ошибку компилятора. Есть ли способ, чем позвонить swap Функция, что я могу сделать это? Я ищу способ сделать это в самой функции.

0

Решение

Вам нужно сохранить значение *first как ваше временное хранилище, а не итератор first,

auto tmp = *first;
*first = *last;
*last = tmp;
first++;

В противном случае вы перезаписываете *first без сохранения его предыдущего значения, и поэтому вы просто копируете из *last в *first (и затем снова копируем его обратно) вместо замены.

Причина, по которой вы получили сообщение об ошибке:

Bi tmp = *first

Это потому что Bi это тип итератора, а не тип значения, которое вы пытаетесь поменять. Чтобы получить правильный тип, вы можете просто использовать auto как я делал выше, или вы можете быть более точным:

typename std::iterator_traits<Bi>::value_type tmp = *first;
2

Другие решения

Других решений пока нет …