You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

我对C++标准中「无副作用」强异常保证的理解是否正确?

C++标准库强异常保证的副作用边界问题

问题核心

C++标准规定std::vector::reserve等库函数具备有条件的强异常保证:若抛出的异常并非来自非Cpp17CopyInsertable类型的移动构造函数,则函数执行「无副作用」。但当自定义类型的拷贝构造函数修改全局状态后抛出异常时,程序全局状态会被改变,看似违反该保证。

标准的明确立场

标准中的「无副作用」仅针对库函数自身的行为和容器的内部状态,完全不涵盖用户自定义操作(如拷贝/移动构造、赋值等)产生的副作用。

相关标准条款覆盖:

在容器通用要求条款[container.reqmts.general]中明确:库函数的异常保证仅约束容器对象本身的状态,不对用户提供的元素操作的副作用负责。
针对std::vector::reserve,[vector.capacity]条款的强异常保证,默认假设用户提供的元素操作(如拷贝构造)的副作用属于用户代码责任,库仅保证容器内部状态回滚至调用前的初始状态。

简言之:C++标准将用户自定义操作的副作用视为用户代码的范畴,库函数只负责维护自身管理的容器状态,不会处理用户操作带来的外部状态变更。

代码示例验证

#include <vector>
#include <stdexcept>

int global_state = 0;

struct CustomType {
    CustomType() = default;
    CustomType(const CustomType&) {
        global_state++; // 用户代码修改全局状态
        throw std::runtime_error("Copy failed");
    }
};

int main() {
    std::vector<CustomType> vec;
    try {
        vec.reserve(1); // 触发拷贝构造并抛出异常
    } catch (...) {}
    // global_state的值为1,而非初始的0,但vec的状态与调用reserve前一致
}

此例中,global_state的修改是用户自定义拷贝构造函数的副作用,不属于标准规定的「无副作用」覆盖范围——标准仅保证vec的容量、元素数量等内部状态未被改变。


内容的提问来源于stack exchange,提问作者Daniel Langr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 21:42:26