我一直在阅读swap()操作,例如:

template<class T>
void swap (T &a, T &b)
{
  T temp (a);
  a = b;
  b = temp;
}

当我们处理异常安全时,这是有问题的。

怎么了
此外,我们该如何解决呢?

最佳答案

在一般的实现中,假设T的任何操作都可以throw,则您不能提供强大的异常保证,这意味着在发生异常事件时,将状态完全保留在操作之前。即使对T的每个操作都提供了强大的异常保证:

template<class T>
void swap (T &a, T &b)
{
  T temp (a);          // [1]
  a = b;               // [2]
  b = temp;            // [3]
}

如果抛出[1],则输入保持不变,这很好。如果抛出[2],并假设有强异常保证,则这些值仍保持不变,这很好。但是,如果抛出的是[3],则a已被修改,这意味着在异常传播到堆栈之后,调用方将处于既不是原始状态也不是最终状态的状态。

编辑:此外,我们如何解决呢?

没有通用的解决方案。但是在大多数情况下,您可以为您的类型提供异常安全的swap操作。考虑一个vector<T>,它通过使用三个指针(beginendcapacity)在内部管理其状态。上面的一般swap可能会抛出(分配失败,内部T的构造函数可能会抛出...),但是提供无抛出swap实现很简单:
template <typename T>
class vector {
   T *b,*e,*c;
public:
   void swap( vector<T>& rhs ) {
      using std::swap;
      swap( b, rhs.b );
      swap( e, rhs.e );
      swap( c, rhs.c );
   }
//...
};
template <typename T>
void swap( vector<T>& lhs, vector<T>& rhs ) {
   lhs.swap(rhs);
}

因为不能复制指针,所以上面的swap提供了不抛出保证,并且如果您始终按照上述模式实现swap(using std::swap;后跟对swap的不合格调用),ADL将把它作为比std::swap更好的匹配对象。

关于c++ - 关于swap()操作的异常安全性-这怎么了?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11485776/

10-13 08:12