我对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
相关产品推荐
相关产品推荐

