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

时间:2016-02-16 22:18:41

标签: c++ c++11 language-lawyer unordered-map noexcept

我正在阅读关于SELECT userfbimages_id, count( * ) FROM votes GROUP BY userfbimages_id HAVING count( * ) >= ALL (SELECT count( * ) FROM votes GROUP BY userfbimages_id) 的{​​{3}}。该 C++ reference pageempty方法已std::unordered_map限定,但不是size

我不认为它应该投入noexcept

我错过了什么吗?

1 个答案:

答案 0 :(得分:7)

因为要求如此说明:

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

n3337 23.2.5 / 5 [unord.req]

  

如果容器的键等式谓词在传递这些值时返回std::unordered_map,则类型k1的两个值k2Key被视为等效。 ...对于同一容器中的任意两个键truek1,调用k2应始终返回相同的值。 ...

对于无序地图,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; 上可以找到的唯一限制也适用于key_type

n3337 23.2.5 / 9 [unord.req] 2

  

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

因此,我们只需要了解表96中对mapped_type的要求,该要求指定了value_type的要求。在第一行中,我们有:

n3337,表96 3

  

Container |返回X::value_type | 要求: TT

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

n3337,表24

  

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

uu类型的对象,符合T的要求

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

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

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

  

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

     

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

     

...

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

...

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

注意:

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

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

3。 noexcept要求也列在n4140的表96中,并列出了ContainerErasable的要求,该要求对T <没有任何限制/ p>

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