I was reading C++ reference page about std::unordered_map
. The
empty
and size
methods are noexcept
qualified, but not count
.
I don't think it should throw in count
.
Am I missing something?
Because the requirements say so:
count
returns the number of elements matching a specific key, and key comparisons are evaluated off of an object of type X::key_type
for any unordered associative container type X
(instantiated std::unordered_map
s are such containers)
n3337 23.2.5/5 [unord.req]
Two values
k1
andk2
of typeKey
are considered equivalent if the container’s key equality predicate returnstrue
when passed those values. ... For any two keysk1
andk2
in the same container, callingpred(k1, k2)
shall always return the same value. ...
For an unordered map, X::key_type
is defined as part of its template parameter list:
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;
The only constraints I can find on key_type
also apply to value_type
:
n3337 23.2.5/9 [unord.req]2
... the requirements placed on
value_type
in Table 96 apply instead tokey_type
andmapped_type
.
So we just need to know the requirements placed on value_type
in table 96, which specifies the requirements for a Container
. In the very first row, we have:
n3337, table 963
X::value_type
| ReturnsT
| Requires:T
isDestructible
where X
is again the type of the Container, and T
is the type of objects it's storing. Destructible
objects are not allowed to have throwing destructors. That's their only requirement.
n3337, table 24
u.∼T()
All resources owned byu
are reclaimed, no exception is propagated
(u
being an object of type T
which fulfills the requirements of Destructible
)
Thus, there is no restriction on the throw guarantees offered by the key comparison function for the unordered_map
, and so no guarantee on the operator==
operation provided from std::equal_to
to implement the required behavior. The key itself lacks any such restrictions, so: the comparison function is allowed to throw, and any function which uses the comparison function is also allowed to throw. count
needs to count the stored values with keys that match the supplied key with the comparison function, so it may throw.
clear
may be noexcept
because the standard bans throwing in destructors:
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.
...
since the only client-dependent code clear
executes may not throw exceptions, and the implementation doesn't need to, it may be and has been marked noexcept
Notes:
1. The n4140 standard draft (near c++14) does not appear to have changed this clause at all.
2. n4140 retains this phrasing, moved to clause 10 from clause 9.
3. The Container
requirements are also listed in Table 96 of n4140, and list the requirement for T
as being Erasable
, which also places no restrictions on operator==
4. The wording of this clause hasn't changed in n4140.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With