您可以自由地共享和演绎本文稿, 只需遵守开源协议[CC By 4.0]
如果这篇文章帮助到你, 可以请我喝一杯咖啡~
在STL容器空间配置与填充/复制初始化过程中,存在一个重要的思想Commit or Rollback
。
它的意义是:若在填充/复制初始化一个容器中的实例序列过程中,有某一个实例初始化失败并抛出异常,那么程序需要立即终止初始化并析构所有在这之前初始化的容器中的实例,以免产生一个初始化一部分的容器,最后将异常转发出去,这就是Commit or Rollback规则。
很直观地,能够产生构造错误的实例只有可能是非标量类型(即non-POD类型),因为这些类型有着自定义的构造方法,且类型中很有可能含有指针,所以有可能会释放异常。所以我们需要针对这种情况作出相应的实现上的优化。
所幸,在标准STL容器中,轮子制造者已经替我们考虑了这种情况并将其封装为一个通用方法,类似于:
template <class forward_iterator, class value_type>
inline void
__uninitialized_fill(forward_iterator start, forward_iterator end,
const value_type &value, __false) {
forward_iterator __start = start;
try {
for (; start != end; start++) {
construct(&*start, value);
}
}catch (...) { // commit or rollback
AMI_std::destroy(&*__start, &*start);
throw;
}
}