提问者:小点点

std::set上的异常安全事务


std::set<T> e;

void f(/* Some parameters. */) {
    /* Some non-throwing code. */

    try {
        e.erase(a);
        e.insert(b);
        e.erase(c);
    } catch(...) {
        // Undo failed operations.
    }
}

我想让f有一个很强的异常保证,不管类型T如何。比如说,擦除a并插入b成功,但擦除c抛出。然后我必须撤消前两个操作,但那将涉及到从catch块中的e中插入和擦除,但这些操作也可以抛出。有什么方法可以执行这个回滚吗?我用的是C++17。


共1个答案

匿名用户

因此,如果某些东西被破坏,那么强异常保证几乎总是被抛弃的。

当由于异常而运行堆栈展开时,如果析构函数抛出程序调用,std terminate的原因与此基本相同。

在添加时,您可以只复制整个集合,然后添加到DupleCate,然后交换集合。然后你就可以把复制品弄到手了;但如果毁灭发生了,那就真的没有一个明智的选择了。不再需要说明此数据,并被告知此操作失败。那到底是什么意思?如何撤消“此数据不需要”?

Requure查找(或)是无异常的。对破坏也一样。则也是nothrow。不要自找麻烦,设定疯子类型;大多数疯狂的类型(它们可以存在)可以被包装在一个sanity-wrapper中,并且在其他时候处理异常。