gpt4 book ai didi

c++ - 关于 swap() 操作的异常安全——这有什么问题?

转载 作者:可可西里 更新时间:2023-11-01 15:38:17 26 4
gpt4 key购买 nike

我一直在阅读 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com