Is there a reason for missing transparent (template <class K> at(K&& key);
) in std::map
?
My guess is that std::map::at()
must be a "bounds-checked" version of std::map::operator[]()
. Providing a transparent version of std::map::operator[]()
imposes an additional requirement on std::map::key_type
and the query key type K
- if the query key is not in the map, it must be inserted (with default constructed value), which means that std::map::key_type
must be constructible from the query key type.
find
, but there's a transparent find
. –
Luo find
is an established operation for multimaps too. –
Bergschrund at
is an established non-option for multimaps. Okay, makes sense now, thanks :) –
Luo find
instead of at
on a std::map<std::string, T>
using a std::string_view
key if they want to avoid constructing a temporary std::string
for the access. Kinda sucks. –
Ischia at
which never constructs map elements. –
Ischia P2363 proposes to add a heterogenous key overloads for at
, as well as try_emplace
, insert_or_assign
, operator[]
, insert
and bucket
(the latter for unordered maps). It missed inclusion into C++23 and is marked as pending for C++26.
A summary of a review conducted on P2363 can be found here on Github. Sorry, I don't know how to find the original review; it might not even be publicly available.
In that review summary, there is this comment:
Currently, for heterogeneous lookup, the unique-key associative containers do not require that there is at most one match ...
I think the paper should discuss what happens in such cases, particularly for insert_or_assign, operator[], and at (and what try_emplace returns on failure)
I believe that comment answers why a heteregenous overload was not provided for at()
for C++14 or C++17.
My conclusions (which jives with T.C.'s comments in the other answer):
Heterogenous lookups for std::map
currently do not require that there be at most one match. For the at()
function, such lookups would have to either:
- be constrained to 0..1 matches, or,
- access the first element that meets the criteria for key equivalence (or throw if none found).
There may not have been consensus on what the behavior should be, which may be why at()
was left out of the proposals that introduced heterogenous keys in C++14 and C++17. Or perhaps they felt that at
is semantically only meaningful for accessing a unique element without ambiguity (the reason why there's no at
in multimaps).
Note that there's no way to check at compile-time whether a heterogeneous key matches one element at most.
For reference, this is the proposal that introduced heterogeneous keys for C++14: N3657 Adding heterogeneous comparison lookup to associative containers. There's no mention of at()
in it.
This is the proposal that introduced heterogenous lookups for unordered containers in C++20: P0919 Heterogeneous lookup for unordered containers.
This is the proposal that introduced heterogenous key for erasure: P2077 Heterogeneous erasure overloads for associative containers, which is marked as approved for C++23.
© 2022 - 2024 — McMap. All rights reserved.
operator[]
either – Xylonfind
. – Angevinfind
is expected to be transparent, simply because the same find expressed as explicit loop would be transparent. – BookshelfKey
for both operations. It's a valid question and contrast. – Angevin