0

据说复制和交换习语提供了强大的异常保证。但在 C++11 中,std::swap 使用移动操作。

考虑以下代码:

class MyClass
{
    AClass x;
    CanThrowIfMoved throwingObject;

    MyClass(MyClass&& other) noexcept
        x(std::move(other.x)),
        throwingObject(std::move(other.throwingObject))
    { }

    friend void swap(MyClass& first, MyClass& second) noexcept
    {
        using std::swap;
        swap(first.x, other.x);
        swap(first.throwingObject, other.throwingObject);
    }

    MyClass& operator=(MyClass other) noexcept
    {
        swap(*this, other);
        return *this;
    }
};

如果throwingObject在交换期间抛出,则强异常保证被打破。

关键字在noexcept编译期间不强制执行任何操作。throwingObject还是可以扔的,唯一的区别就是程序会猛烈terminate。我不认为在发生异常时使整个应用程序崩溃算作强大的异常保证。

这是否意味着复制和交换不再强制执行 C++11 中的强异常保证?


类似问题

这个问题类似,但它的目标是使用标准库。我对这个问题对于复制和交换习语的强例外保证意味着什么很感兴趣。

这个问题讨论了如何noexcept在copy-and-swap成语中使用,但只讨论了copy。不是交换,这似乎是问题所在。

4

1 回答 1

2

不是直接调用成员方法swap,而是swap使用辅助函数模板,它在编译时检查noexcept保证:

friend void swap(MyClass& first, MyClass& second) noexcept
{
    util::swap_noexcept(first.x, other.x);
    util::swap_noexcept(first.throwingObject, other.throwingObject);
}

namespace util
{
    template <typename ...Args>
    void swap_noexcept(Args&&... args) noexcept
    {
        using std::swap;
        static_assert(noexcept(swap(std::forward<Args>(args)...)), "requires noexcept");
        swap(std::forward<Args>(args)...);
    }
}
于 2014-06-26T19:06:53.473 回答