Copy_backward или копировать с помощью reverse_iterators?
В терминах практического использования существуют различия между
a) copy_backward
b) копировать с помощью reverse_iterators для источника и адресата
В частности, это более общеприменимо, чем другое? Есть ли другие отличия?
Обновление: если на самом деле нет разницы, то любая ссылка в литературе С++ на эту эквивалентность оценивается. Мотивация, стоящая за этим вопросом, заключается в том, чтобы понять, было ли это по дизайну или одному из этих промахов (например, missing copy_if)
Ответы
Ответ 1
Прежде всего, использование copy_backward() явно показывает намерение разработчика скопировать интервал в обратном порядке.
copy_backward() работает с оригинальными двунаправленными итераторами, в то время как reverse_iterator является адаптером двунаправленного итератора и может быть не таким эффективным, как оригинальный итератор.
Использование reverse_iterator имеет смысл, когда вам нужно применить алгоритм ввода итераторов типа copy() для обратной последовательности, но не иметь аналогов для двунаправленных операторов, таких как copy_backward().
Поэтому существуют концептуальные и практические различия.
Ответ 2
http://www.cplusplus.com/reference/algorithm/copy/ имеет реализацию std::copy
http://www.cplusplus.com/reference/algorithm/copy_backward/ имеет реализацию std::copy_backward
Вы можете увидеть различия самостоятельно.
Примечание.. Если бы я был вами, я бы использовал std::copy_backward
, потому что вызов std::copy
с классом std::reverse_iterator<T>
может быть немного медленнее (для этого требуется больше памяти, чем двунаправленный итератор)
Ответ 3
Разница в том, что copy
возвращает итератор в элемент pass-end, а copy_backward
возвращает итератор в первый элемент.
В этом смысле они не эквивалентны.
- Подписи, конечно, различаются.
copy
в порядке с InputIterator
и OutputIterator
. Пока copy_backward
ожидает BidirectionalIterator
s.
- Влияние на контейнер (при правильном использовании) одинаково, но возвращенные итераторы имеют разные типы и указывают на разные элементы.
Пример:
Это работает, потому что vector
может использовать RandomAccessIterator
, который поддерживает свойства, ожидаемые InputIterator
, OutputIterator
и BidirectionalIterator
.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void printer(int i) {
cout << i << ", ";
}
int main() {
int mynumbers[] = {3, 9, 0, 2, 1, 4, 5};
vector<int> v1(mynumbers, mynumbers + 7);
vector<int>::iterator it = copy_backward(mynumbers, mynumbers + 7, v1.end());
for_each(v1.begin(), v1.end(), printer);
cout << endl << "Returned element: " << *it;
cout << endl;
vector<int>::reverse_iterator rit = copy(mynumbers, mynumbers + 7, v1.rbegin());
for_each(v1.begin(), v1.end(), printer);
cout << endl << "Before the first element (reverse end)? " << (rit == v1.rend());
rit--; // go to first element, because it is a reverse iterator
cout << endl << "Returned element: " << *rit;
return 0;
}
Результат:
3, 9, 0, 2, 1, 4, 5,
Returned element: 3
5, 4, 1, 2, 0, 9, 3,
Before the first element (reverse end)? 1
Returned element: 5
Если вы используете контейнер, который не поддерживает BidirectionalIterator
, тогда вы рискуете неприятностями (например, если вы попытаетесь скопировать назад a forward_list
, потому что он использует ForwardIterator
, который не поддерживает выполняемые операции на BidirectionalIterator
).
Также в этом случае копирование с обратным итератором на forward_list
также невозможно, так как оно не поддерживает обратные итераторы.
В принципе, вам нужно убедиться, что итераторы контейнера поддерживаются и выбирают в зависимости от того, какой конец контейнера вы хотели бы вернуть. В противном случае эффект будет таким же.
Ответ 4
Никаких различий практически нет.
Аналогичным образом вы можете сравнить форматированное копирование.
a) скопировать
b) copy_backward с обратными итераторами.
Ответ 5
Однако не должно быть никакой разницы:
copy_backward пригодится в случае, если итератор является результатом некоторого вызова функции, а также намного чище, чем использование копии с помощью обратных итераторов.