C++ 为什么std::unordered\u map::count上没有'noexcept'说明符?
我在读关于std::无序地图的文章。这个 方法是C++ 为什么std::unordered\u map::count上没有'noexcept'说明符?,c++,c++11,language-lawyer,unordered-map,noexcept,C++,C++11,Language Lawyer,Unordered Map,Noexcept,我在读关于std::无序地图的文章。这个 方法是noexcept限定的,但不是 我认为它不应该加入count 我遗漏了什么吗?因为要求是这样说的: count返回与特定键匹配的元素数,并针对任何无序关联容器类型X对类型为X::key\u type的对象计算键比较(实例化的std::unordered\u map就是这样的容器) n3337 23.2.5/5[未通知要求] 如果容器的键相等谓词在传递这些值时返回true,则类型为Key的两个值k1和k2被认为是等效的。。。对于同一容器中的任意两个键
noexcept
限定的,但不是
我认为它不应该加入count
我遗漏了什么吗?因为要求是这样说的:
count
返回与特定键匹配的元素数,并针对任何无序关联容器类型X
对类型为X::key\u type
的对象计算键比较(实例化的std::unordered\u map
就是这样的容器)
n3337 23.2.5/5[未通知要求]
如果容器的键相等谓词在传递这些值时返回true
,则类型为Key
的两个值k1
和k2
被认为是等效的。。。对于同一容器中的任意两个键k1
和k2
,调用pred(k1,k2)
将始终返回相同的值
对于无序映射,X::key\u type
被定义为其模板参数列表的一部分:
template<
class Key,
// ^^^ member type key_type set from this parameter
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
// ^^^^^^^^ member type key_equal set from this parameter
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
模板<
类密钥,
//^^^^成员类型键\根据此参数设置的类型
T类,
类Hash=std::Hash,
类KeyEqual=std::等于,
//^^^^^^^^^^成员类型键_等于此参数设置的值
类分配器=std::分配器
>类无序图;
我在键类型
上找到的唯一约束也适用于值类型
:
n3337 23.2.5/9[unord.req]2
。。。表96中对值类型
的要求适用于键类型
和映射类型
因此,我们只需要知道表96中value\u type
的要求,表96规定了容器的要求。在第一排,我们有:
n3337,表963
X::value_type
|返回T
|要求:T
是可破坏的
其中,X
又是容器的类型,T
是它存储的对象的类型<代码>可破坏的
对象不允许有抛出析构函数。这是他们唯一的要求
n3337,表24
u。∼T()
回收u
拥有的所有资源,不传播任何异常
(u
是满足可破坏性要求的T
类型的对象)
因此,对键比较函数为无序映射
提供的抛出保证没有任何限制,因此,操作符==
在std::equal\u to
中提供的实现所需行为的操作没有任何保证。键本身没有任何此类限制,因此:允许比较函数抛出,也允许使用比较函数的任何函数抛出。count
需要使用与提供的键与比较函数匹配的键对存储值进行计数,因此它可能抛出
clear
可能是noexcept
,因为标准禁止抛出析构函数:
17.6.4.8/1,24[关于功能的决议]
在某些情况下(替换函数、处理函数、用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件。如果这些组件不满足其要求,则标准不会对实现提出任何要求
特别是,在以下情况下,影响未定义:
- 如果任何替换函数或处理函数或析构函数操作通过异常退出,除非适用的必需行为:段落中明确允许
由于执行的唯一依赖于客户端的代码clear
可能不会抛出异常,并且实现不需要抛出异常,因此它可能已经被标记为noexcept
注:
一,。n4140标准草案(接近c++14)似乎根本没有改变这一条款
二,。n4140保留该措辞,从第9条移至第10条
三,。n4140的表96中也列出了容器
的要求,并列出了T
的要求,这也对操作员==
四,。在n4140中,该子句的措辞没有改变。我认为没有任何东西阻止散列函数或相等谓词抛出。好的。我还想知道为什么指定了noexcept
。存储实例可能会抛出其析构函数。为什么会有不同的行为?@RichardDally:析构函数不能抛出exceptions@MooingDuck析构函数可以抛出,尽管它被认为是拙劣的样式purpose@M.M:我查过了,你是对的。默认情况下,它们不能抛出,但如果您显式地将它们标记为noexcept(false)
,则它们可以抛出。[res.on.functions]/2.4禁止全面抛出析构函数,并且至少从C++03起就这样做了。@T.C.已修复。再次感谢你给我这个条款。