为什么STL容器中的交换成员函数没有声明为noexcept? 标准的C++要求容器的代码>交换< /代码>函数不抛出任何异常,除非指定否则 [容器。要求。一般] < /代码>(23.2.1节10)。
为什么STL容器中的交换成员函数没有声明为noexcept? 标准的C++要求容器的代码>交换< /代码>函数不抛出任何异常,除非指定否则 [容器。要求。一般] < /代码>(23.2.1节10)。,c++,c++11,swap,noexcept,C++,C++11,Swap,Noexcept,为什么指定为不抛出的swap成员函数未声明noexcept 同样的问题也适用于专门的非成员交换重载 一开始听起来可能有些奇怪,但没有明确说明标准容器的swap是noexcept是故意的;这一切归结为未定义的行为(UB) 23.2.1p9一般集装箱要求[Container.Requirements.General] 用于标准容器a和b的表达式a.swap(b) 除数组以外的容器类型应交换a 和b,而不调用服务器上的任何移动、复制或交换操作 单个容器元素 属于a和b的任何Compare、Pred
- 为什么指定为不抛出的
成员函数未声明swap
noexcept
同样的问题也适用于专门的非成员
交换重载 一开始听起来可能有些奇怪,但没有明确说明标准容器的swap
是noexcept
是故意的;这一切归结为未定义的行为(UB)
23.2.1p9
一般集装箱要求[Container.Requirements.General]
用于标准容器a
和b
的表达式a.swap(b)
除数组
以外的容器类型应交换a
和b
,而不调用服务器上的任何移动、复制或交换操作
单个容器元素
属于a
和b
的任何Compare
、Pred
或Hash
对象都应
可交换,且应通过非会员的非限定呼叫进行交换
交换
如果
Alisdair Meredith和John Lakos在这件事上发表了名为“noexcept
阻止库验证”的文章
简而言之,它讨论了noexcept
如何阻止库实现在库代码(即标准库的实现)中使用断言,甚至在调试模式下,以及这一点的含义
<如果C++有一个标准化的“测试”和“生产”模式(如本文所称的那样),在代码> >除了< /代码>有条件地应用,这将远没有问题。但就目前情况而言;C++没有“模式”。 另外,这里有一个来自Daniel Kr U.GLER的关于<代码> STD讨论< /代码>邮件列表:
的帖子。
将函数声明为无条件noexcept的内部策略是
解释
使用本文中使用的术语,std::vector的swap函数
有一个缩小的合同,就是它有关于
参与对象的分配器。这意味着,存在
呼叫者可能违反先决条件和
应该允许实现以我不同的方式发出这一信号
而不是通过终止。因此,这些功能也不例外,
但它应该有一个有效的元素“抛出:没有”,因为
适用于满足前提条件的情况
()
内部策略是对你的问题的规范的、官方的回答。我猜他们可能错过了。你在使用哪一个C++库?@ MatsPutsson我只是在看裸露的标准,而不是一个特定的实现。这可以帮助:“永远”:我把它复制成答案,因此,它正式存在于本问答中。为什么将分配器与数据一起交换会有问题?这是对UB定义的一个有趣的理解。不要说这是错的。@GreenScape我会把你的评论/问题放到一个新的问答中,有问题的时候我会打电话给你。@GreenScape这应该能回答你的问题:如果打电话的人违反了先决条件,这不是一个普通的错误吗?如果调用者假定
swap()
函数不能抛出,但它仍然抛出(因为违反了先决条件),那么再见异常安全和保留不变量。程序也可以terminate()
@RalphTandetzky:是的,实现可以做到这一点。不过,标准是对这样的计划不作任何要求。没有要求。没有一个