Подтвердить что ты не робот

С++ STL copy() безопасность исключений

Если я делаю

std::copy(source, source + size, destination);

Есть ли у меня надежная гарантия безопасности? То есть если std:: copy throws, назначение остается неизменным?

4b9b3361

Ответ 1

Из стандарта:

25.3.1 Копирование [alg.copy]

template<class InputIterator, class OutputIterator>
   OutputIterator copy(InputIterator first, InputIterator last,
                       OutputIterator result);

1 Эффекты: копирует элементы в диапазоне [first,last) в диапазон [result,result + (last -first)) начиная с first и переходя к last. Для каждого неотрицательного целого n < (last -first) выполняется *(result + n) = *(first + n).

2 Возвращает: result + (last - first).

3 Требуется: result не должно находиться в диапазоне [first,last).

4 Сложность: точно last - first назначения.

Он не гарантирует никаких гарантий безопасности исключений. В нем также не указывается, каково будет поведение, если result находится в диапазоне [first,last).

Ответ 2

Приложение E: Безопасность исключений стандартной библиотеки из Stroustrop Язык программирования С++ свободно доступен для просмотра с его сайта.

Из этого:

Алгоритм copy() (§18.6.1) не предлагает сильного гарантия безопасности исключения. Это не гарантирует, что он оставит свою цель без изменений, если исключение бросается во время копирования

Ответ 3

Быстрый поиск по разделу 25 (предложение, определяющее большинство стандартных алгоритмов) показывает, что нет экземпляра фразы без эффектов, а стандарт определяет сильную защиту исключений как "если выбрано исключение (есть/функция имеет ) никаких эффектов". Другими словами, ничто в пункте 25 не содержит надежной гарантии безопасности.

Кроме того, как std::copy может предложить сильную гарантию безопасности исключений? dest может быть произвольным выходным итератором, который не обязательно читается и может выполнять произвольные операции над записью. Что, если это std::ostream_iterator - как вы "не записываете" то, что было записано в поток?

Ответ 4

Копия определена в 25.3.1 как

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).
4 Complexity: Exactly last - first assignments.

Что может быть эффективно записано как:

template<class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = *first;
    ++result; ++first;
  }
  return result;
}

Способ форматирования, если исключение происходит в любое время после первого выполнения цикла, тогда пункт назначения будет изменен.