Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::unordered\u map::count上没有'noexcept'说明符?_C++_C++11_Language Lawyer_Unordered Map_Noexcept - Fatal编程技术网

C++ 为什么std::unordered\u map::count上没有'noexcept'说明符?

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被认为是等效的。。。对于同一容器中的任意两个键

我在读关于std::无序地图的文章。这个 方法是
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.已修复。再次感谢你给我这个条款。