6

std::swapC ++標準は、例外をスローしないことを保証します。ただし、スワップするオブジェクトがスワップ中に例外をスローした場合はどうなりますか?次に、呼び出し元は例外が発生したことをどのように見つける必要がありますか?発信者はどのような対策を講じる必要がありますか?

PS:コンストラクターが例外をスローすることは非常に一般的です。

struct A
{
    A(const A&)
    {
        throw 1;
    }

    A& operator =(const A&)
    {
        throw 2;
        return *this;
    }
};

int main()
{
    A a1, a2;
    std::swap(a1, a2); // An exception happened, but the caller doesn't know.
    // How to do here ???
}
4

2 に答える 2

16

C ++標準は、std::swapが例外をスローしないことを保証します。

いいえ、そうではありません。20.2.2またはリファレンスを参照してくださいstd::swap2つのオーバーロードには2つの例外のない仕様があります。

template<class T> void swap(T& a, T& b)
noexcept(noexcept(
    std::is_nothrow_move_constructible<T>::value &&
    std::is_nothrow_move_assignable<T>::value
))

template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N])    
noexcept(noexcept(swap(*a, *b)))

これらの条件が満たされない場合、std::swap投げることができ、あなたはそれを捕まえることができます。


提示したクラスの場合、述語std::is_nothrow_move_constructiblestd::is_nothrow_move_assignableはfalseであるため、インスタンス化にstd::swap<A>はスローなしの保証はありません。このスワップからの例外をキャッチすることは完全に合法です。

于 2013-01-30T10:23:09.053 に答える
10

この規格は通常、スワップがスローされないことを保証していません。

20.2.2 / 1から:

テンプレートvoidswap(T&a、T&b)noexcept(以下を参照);

備考:noexcept内の式は、次と同等です。

 is_nothrow_move_constructible<T>::value &&
 is_nothrow_move_assignable<T>::value
于 2013-01-30T10:27:18.503 に答える