Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why heterogeneous comparison lookup is not implemented for `at` and `operator []`?

Tags:

c++

c++14

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
like image 802
Nicolas Avatar asked Sep 02 '15 17:09

Nicolas


People also ask

What is heterogeneous lookup?

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.

What is std :: less?

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.


1 Answers

There are no logical reasons in principle for it. For example for operator[] a reasonable semantic could be

  • If the passed value is comparable with 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).
  • If in the case before the passed type is not convertible to key_type the use of operator[] should just not compile (like it happens now)
  • If the passed type cannot be compared with 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).

like image 88
6502 Avatar answered Nov 15 '22 18:11

6502