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

Why is there no `noexcept` specifier on std::unordered_map::count?

我正在阅读 C++ reference page 关于 std::unordered_map 的内容。这 empty and size methods are noexcept qualified, but not count.

我认为它不应该放入 count

我是不是漏掉了什么?

因为要求是这样说的:

count returns 与特定键匹配的元素数量,键比较是针对任何无序关联容器类型 X::key_type 类型的对象进行评估的 X(实例化的std::unordered_map就是这样的容器)

n3337 23.2.5/5 [unord.req]

Two values k1 and k2 of type Key are considered equivalent if the container’s key equality predicate returns true when passed those values. ... For any two keys k1 and k2 in the same container, callingpred(k1, k2) shall always return the same value. ...

对于无序映射,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;

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

n3337 23.2.5/9 [unord.req]2

... the requirements placed on value_type in Table 96 apply instead to key_type and mapped_type.

所以我们只需要知道在table96中对value_type的要求,它规定了对Container的要求。在第一行,我们有:

n3337, table 963

X::value_type | Returns T | Requires: T is Destructible

其中 X 也是容器的类型,T 是它存储的对象的类型。 Destructible对象不允许有抛出析构函数。这是他们唯一的要求。

n3337, table 24

u.∼T() All resources owned by u are reclaimed, no exception is propagated

u 是满足 Destructible 要求的 T 类型的对象)

因此,对于 unordered_map 的键比较函数 提供的抛出保证没有限制,因此 operator== 也没有保证std::equal_to 提供的操作以实现所需的行为。 key本身没有任何这样的限制,所以:比较函数允许抛出,任何使用比较函数的函数也允许抛出。 count需要计数具有与提供的键与比较函数匹配的键的存储值,因此它可能会抛出。


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

17.6.4.8/1,24 [res.on.functions]

In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, the Standard places no requirements on the implementation.

In particular, the effects are undefined in the following cases:

...

  • if any replacement function or handler function or destructor operation exits via an exception, unless specifically allowed in the applicable Required behavior: paragraph.

...

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


备注:

1. n4140 标准草案(接近 c++14)似乎根本没有更改此条款。

2。 n4140 保留此措辞,从第 9 条移至第 10 条。

3。 Container的要求也在n4140的Table96中列出,将T的要求列为Erasable,对operator==也没有限制

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