C++ STL 的 copy() 异常安全

C++ STL's copy() exception safety

如果我这样做

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

我有很强的异常安全保障吗? IE。如果 std::copy 抛出,目的地保持不变?

来自标准:

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).

4 Complexity: Exactly last - first assignments.

它不对异常安全性做任何保证。如果 result[first,last).

范围内,它也没有指定行为是什么

复制在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;
}

如果在第一次执行循环后任何时候发生异常,则格式化的方式将更改目标。

快速搜索第 25 条(指定大多数标准算法的条款)表明没有短语 no effects 的实例,并且该标准将强异常安全性指定为 "if an exception is thrown (there are/the function has) no effects"。换句话说,第 25 条中没有任何内容具有强大的异常安全保证。

而且,std::copy怎么可能提供强大的异常安全保障呢? dest 可以是一个任意的输出迭代器,它不一定是可读的,并且可以在写入时执行任意操作。如果它是 std::ostream_iterator 怎么办 - 你如何 "un-write" 写入流的内容?

附录 E:标准库异常安全 来自 Stroustrop 的 C++ 编程语言freely viewable from his website

来自:

The copy() algorithm (§18.6.1) does not offer the strong exception-safety guarantee. It does not guarantee that it will leave its target unchanged if an exception is thrown during copying