Since C++14 (N3657) member function templates find
, count
, lower_bound
, upper_bound
, and equal_range
of associative containers support heterogeneous comparison lookup but at
and operator[]
don't have those equivalent member function templates. Why is that so ?
Example :
std::map<std::string, int, std::less<>> m;
// ...
auto it = m.find("foo"); // does not construct an std::string
auto& v = m.at("foo"); // construct an std::string
To avoid this unnecessary work, some containers provide heterogeneous lookup. This feature allows callers to pass keys of any type (as long as the user-specified comparator functor supports them). See std::map::find for an example of this feature in an STL container.
The std::less is a is a member of the functional class (<functional. h>) used for performing comparisons. It is defined as a function object class for less than inequality comparison which returns a boolean value depending upon the condition. This can be used to change the functionality of the given function.
There are no logical reasons in principle for it. For example for operator[]
a reasonable semantic could be
key_type
do the search using it and convert to key_type
only if needed (i.e. if the element is not found and the container is neither const nor accessed using a const reference).key_type
the use of operator[]
should just not compile (like it happens now)key_type
but can be converted to key_type
then a temporary should be created immediately to do the search and possibly the insertion (like it's now).Of course there should be a requirement to have x < y
for a T
element x
and a key_type
element y
if and only if key_type(x) < y
because otherwise semantic would be nonsense (like it would be nonsense for example to have operator<
to return a value based on a random source).
Unfortunately C++ template machinery is at the same time extremely complex and extremely weak and implementing the conversion to key_type
for operator[]
only when really necessary is probably more complex than it seems.
This machinery is however what the C++ community decided to condemn itself to use for metaprogramming and until someone manages out to get a decent implementation using only that, this reasonable requirement is probably not going to be in the standard (in the past it happened that the standard mandated things that were fuzzily defined and/or basically impossible to implement like template export, and it wasn't funny).
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