为什么std :: unordered_map :: count上没有`noexcept`说明符?

Ric*_*lly 4 c++ unordered-map language-lawyer noexcept c++11

我正在阅读关于C++的参考页面std::unordered_map.这些 emptysize方法是noexcept合格的,但不是count.

我不认为它应该投入count.

我错过了什么吗?

jag*_*ire 7

因为要求如此说:

count返回与特定键匹配的元素的数量,并且X::key_type对于任何无序的关联容器类型,对类型的对象评估键比较X(实例化的std::unordered_maps是这样的容器)

n3337 23.2.5/5 [unord.req]

如果容器的键等式谓词在传递这些值时返回,则两个值k1k2类型Key被认为是等效的true....对于任何两个键k1k2同一个容器,调用pred(k1, k2)应始终返回相同的值....

对于无序映射,X::key_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;
Run Code Online (Sandbox Code Playgroud)

我能找到的唯一限制key_type也适用于value_type:

n3337 23.2.5/9 [unord.req] 2

...... value_type表96中的要求适用于key_typemapped_type.

因此,我们只需要知道value_type表96中的要求,该要求指定了a的要求Container.在第一行中,我们有:

n3337,表96 3

X::value_type| 返回T| 要求: TDestructible

where X再次是Container的类型,并且T是它存储的对象的类型.Destructible对象不允许抛出析构函数.这是他们唯一的要求.

n3337,表24

u.?T()所有拥有的资源u都被回收,不会传播任何异常

(u作为T满足要求的类型的对象Destructible)

因此,存在由键比较函数提供的罚球保证没有限制unordered_map,所以在不能保证operator==从提供的操作std::equal_to来实现所需的行为.密钥本身没有任何这样的限制,因此:允许比较函数抛出,并且允许使用比较函数的任何函数抛出. count需要使用与提供的键匹配的键和比较函数来计算存储的值,因此它可能会抛出.


clear可能是noexcept因为标准禁止投掷析构函数:

17.6.4.8/1,2 4 [res.on.functions]

在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件.如果这些组件不符合要求,则标准对实施没有要求.

特别是,在以下情况下,效果未定义:

...

  • 如果任何替换函数或处理函数或析构函数操作通过异常退出,除非在适用的必需行为:段落中明确允许.

...

因为唯一依赖于客户端的代码clear执行可能不会抛出异常,并且实现不需要,它可能已被标记noexcept


笔记:

1. n4140标准草案(接近c ++ 14)似乎根本没有改变这一条款.

2. n4140保留这一措辞,从第9条移至第10条.

3.这些Container要求也列在n4140的表96中,并列出了Tas 的要求Erasable,也没有任何限制operator==

4.该条款的措辞在n4140中没有改变.