1

Тема: copy та copy_backward ..(stl)

Таке, мабуть, просте питання: навіщо була затверджена остання функція, адже можна замінити її з copy?
Наведіть мені, будь-ласка, приклад того випадку, де заміна copy_backward функцією copy неможлива.

2 Востаннє редагувалося koala (26.12.2013 20:07:52)

Re: copy та copy_backward ..(stl)

#include <iostream>
#include <algorithm>
#include <string>

int main() {
  std::string str("ABCD");
  std::copy(str.begin(), str.end() - 1, str.begin() +1);
  std::cout << str; //WTF?
}

Згідно з ISO/IEC 14882:2011

25.3.1 Copy [alg.copy]
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);
1 Effects: Copies elements in the range [first,last) into the range [result,result + (last -first)) starting from first and proceeding to last. For each non-negative integer n < (last -first), performs *(result + n) = *(first + n).
2 Returns: result + (last - first).
3 Requires: result shall not be in the range [first,last).

тобто може (залежно від реалізації!) перезаписати джерело, а потім скопіювати перезаписане. Якщо останній параметр потрапляє між першими двома, треба використовувати copy_backward.

3 Востаннє редагувалося incred (26.12.2013 21:24:03)

Re: copy та copy_backward ..(stl)

Із самою специфікацією я знайомий.
А щодо цього рядка:

 std::copy(str.begin(), str.end() - 1, str.begin() +1);

то його можемо замінити таким:

std::copy_backward(str.begin(), str.end()-1, str.end());

результат буде таким же: ми зміщуємо діапазон з str.begin() по str.end()-1  на одну позицію вправо..

Але чому у мене виникло таке питання?
Зараз я вже розглянув багато(відносно багато) функцій з stl, які виконують модифікації діапазону, і приходжу до висновку, що більшість із них, на мою думку, не є такими вже й цінними, бо роботу виконують ту ж саму.

Лишається одне: оскільки ШАБЛОННІ функції(тим паче, у САМІЙ STL!!) не повинні дублюватися, вся суть в реалізації цих функцій. Десь одна ефективніша за іншу. Н-д, цю задачу можна розв'язати за допомогою таких функцій, як rotate, swap_ranges і ті ж самі copy та copy_backward
Або важливішою, ніж я думаю, в stl є семантика.. у чому я дуже сумніваюся....

з.ю.
Звідки той код?
Згідно із цією вимогою

3 Requires: result shall not be in the range [first,last).

не зовсім правильна реалізація. Результат буде знаходитися за межами проміжку. А в тому коді навпаки, результат - у інтервалі.
Я вичитав таке(але, на жаль, це стосується конкретно цього випадку і зовсім не те, що мені треба): для зміщення елементів вліво користуються copy, для зміщення вправо - користують copy_backward. Це пояснюється тим, що, коли ми зміщуємо вправо, ми повинні знаходитися в межах контейнеру, тобто до container.end() нічого додавати не можна(в нашому випадку ми нічого й не додаємо, але компілятор мовчатиме, коли ми так зробимо). Оскільки це є негласне правило(помилка виявляється на етапі виконання), таке обмеження на використання ІСНУЄ у описі функції. Та ж не про те говоримо: чому так багато варантів? Посилатися весь час на ті ж обмеження - це життя у постійному страху перейти межу))))

4

Re: copy та copy_backward ..(stl)

На жаль, весь C++ в цьому.