异常安全的swap

某种类型的可能有的四种swap

  1. std提供的标准版本(基于副本的交换)
  2. 用户自己全特化的std版本(基于impl的交换)
  3. 针对于类型的member版本
  4. 针对于类型的non-member版本(可能处于自己的命名空间里,调用member版本的swap)

手法如何应用?

namespace ns
{
    // 提供一个non-member的版本
    void swap(Bar &x, Bar &y)
    {
        x.swap(y);
    }
}
void doSomething(Foo &x, Foo &y)
{
    using std::swap;
    swap(x, y); // 如果指定命名空间内没有自己提供的non-member swap,就默认调用std的版本
}

异常安全

  • 基本承诺
    所有对象都处于内部前后一致的状态

  • 强烈保证
    如果调用某函数后异常发生,则程序会回到调用函数之前的状态

  • noexcept
    保证不抛异常

copy-and-swap技巧:swap必须noexcept

  • 这个技巧大致是这个意思:如果函数需要对某个变量进行修改,或者输出某些变量,则在一个副本上进行修改或者构造(因为这个过程可能会抛出异常),最后将这个副本和指定对象(成员或者输出)进行swap;
  • 因为swap是不抛异常的(noexcept修饰),所以如果前面的副本构造失败,swap不会执行,提供了上述提到的“强烈保证”
posted @ 2020-07-07 15:26  joeyzzz  阅读(303)  评论(0编辑  收藏  举报