首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我在哪里可以找到标准容器和算法的所有异常保证?

我在哪里可以找到标准容器和算法的所有异常保证?
EN

Stack Overflow用户
提问于 2012-07-28 15:12:22
回答 3查看 4.3K关注 0票数 26

是的,我已经查看了我能找到的C++ standards (或草案),但我没有找到任何全面的由STL容器提供的异常保证。我所能找到的只是一些偶然的章节,对一些类型的一些函数有不完整的描述。也许它就在那里,但我只是找不到它,我不知道。

注意: I'm not要求列出人们能想到的所有保证,这基本上是用this question编写的。

我正在寻找这些信息本身的权威来源--或者最好是来源的免费版本(例如标准草案),在那里我或多或少可以被视为官方的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-07-28 15:48:59

阅读标准可能会很可怕(让我们回到标准),但是Bjarne Stroustrup在他的书“C++编程语言”中写了一个关于这个主题的非常好的附录。他将这篇附录放在

http://www.stroustrup.com/3rd_safe0.html,在http://www.stroustrup.com/3rd_safe.pdf

它很长,很详细(而且写得很好)。例如,你可能会发现E.4节很有趣,引用:

E.4标准容器保证

如果库操作本身抛出异常,它可以-并且确实会-确保它所操作的对象处于定义良好的状态。例如,在()抛出向量的out_of_range (§16.3.3)对于向量的异常安全来说不是问题。at()的编写者可以在抛出之前确保向量处于定义良好的状态。

此外,E.4.1节规定

除了基本的保证外,标准库还为一些插入或删除元素的操作提供了强有力的保证。

请看一下956页。它包含一个用于向量、双队列、列表和映射的各种操作的保证表。总之,这些容器上的所有操作要么不抛,要么强大,除了 N - element insert on ,它提供了基本的保证。

注意:上面的文本是旧的,并没有涉及C++11,但对于大多数目的和目的来说,仍然应该是正确的。

当涉及到C++11..。

标准的第一个声明是关于容器array, deque, forward_list, list, vector, map, set, unordered_map, unordered_set, queue,stack:at

23.2.1/10

除非另有说明(参见23.2.4.1、23.2.5.1、23.3.3.4和23.3.6.5),否则本条款中定义的所有容器类型都满足以下附加要求:

-如果在插入单个元素时,insert()或emplace()函数抛出异常,则该函数不起作用。

-如果push_back()或push_front()函数抛出异常,则该函数无效。

-没有erase()、clear()、pop_back()或pop_front()函数抛出异常。

-返回迭代器的任何复制构造函数或赋值运算符都不会抛出异常。

-没有交换()函数抛出异常。

-没有swap()函数使任何引用、指针或迭代器无效,这些引用、指针或迭代器引用被交换的容器的元素。

在上面提到的各个部分中指出的怪癖(每个称为异常安全保证)主要是关于特殊的对壁情况,比如处理来自所包含类型的散列、比较操作以及抛出交换和抛出移动操作的异常。

票数 18
EN

Stack Overflow用户

发布于 2012-07-28 16:27:59

n3376

23.2.1一般容器需求container.requirements.general

第10段

除非另有说明(参见23.2.4.1、23.2.5.1、23.3.3.4和23.3.6.5),否则本条款中定义的所有容器类型都满足以下附加要求:

-如果在插入单个元素时,insert()或emplace()函数抛出异常,则该函数不起作用。

-如果push_back()或push_front()函数抛出异常,则该函数无效。

-没有erase()、clear()、pop_back()或pop_front()函数抛出异常。

-返回迭代器的任何复制构造函数或赋值运算符都不会抛出异常。

-没有交换()函数抛出异常。

-没有swap()函数使任何引用、指针或迭代器无效,这些引用、指针或迭代器引用被交换的容器的元素。

注意: end()迭代器没有引用任何元素,因此它可能是无效的。-endnote

23.2.4关联容器associative.reqmts

23.2.4.1异常安全保证associative.reqmts.except

clear 1对于关联容器,没有

()函数抛出异常。erase(k)不会抛出异常,除非该异常是由容器的Compare对象(如果有)抛出的。

2对于关联容器,如果插入单个元素的insert或emplace函数中的任何操作抛出异常,则插入无效。

3对于关联容器,任何交换函数都不会抛出异常,除非该异常是由容器的比较对象(如果有)的交换引发的。

23.2.5无序关联容器unord.req

23.2.5.1异常安全保障unord.req.except

clear 1对于无序关联容器,没有

()函数抛出异常。erase(k)不会抛出异常,除非该异常是由容器的Hash或Pred对象(如果有)抛出的。

2对于无序关联容器,如果容器的散列函数以外的任何操作在插入或嵌入单个元素的函数中抛出异常,则插入不起作用。

3对于无序关联容器,任何交换函数都不会抛出异常,除非该异常是由容器的Hash或Pred对象(如果有)的交换引发的。

4对于无序关联容器,如果从rehash()函数中抛出异常,而不是通过容器的散列函数或比较函数抛出异常,则rehash()函数无效。

23.3.3.4双队列修饰符deque.modifiers

无效push_back(T&& x);第2段

备注:如果异常不是由T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符引发的,则没有任何影响。如果非CopyInsertable T的move构造函数抛出异常,则效果未指定。

迭代器擦除( const_iterator first,const_iterator last);第6段

抛出:除非T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符引发异常,否则不抛出任何异常。

23.3.6.5向量修饰符vector.modifiers

无效push_back(T&& x);第2段

如果非CopyInsertable T的move构造函数抛出异常,则效果未指定。

迭代器擦除( const_iterator first,const_iterator last);第5段

抛出:除非T.

的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符引发异常,否则不抛出任何异常。

票数 10
EN

Stack Overflow用户

发布于 2012-07-29 04:25:21

您所链接的文档,即n3337草案标准,可以被视为官方文档。它是C++11标准加上一些小的编辑改动。

你只需要学会阅读标准,这是可以理解的,因为它并不是为了让人容易阅读。

要查找任何特定库操作的异常保证,请查看该操作的规范中有关异常的注释和注释。如果该函数是一个成员函数,那么检查该类型的规范,了解有关异常安全性的注释以及它满足的要求。然后检查满足需求的异常保证,这些异常保证必须由对象做出才能满足这些需求。

对于泛型类型和算法,还要检查对模板参数的要求,以了解这些类型必须满足哪些要求,才能保持类型或算法或成员函数所做的所有异常保证(如果模板参数不满足指定的要求,则将模板与这些参数一起使用具有未定义的行为,并且模板的规范都不适用)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11699083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档