If there is a std::map<std::pair<std::string, std::string>, some_type> what is the best way to find its values?
I guess the most obvious one is to do something like this:
map.find(std::make_pair(str1, str2));
but this will lead to a copy-construction of the str1 and str2 strings during the pair construction.
I hoped that maybe map.find(std::make_pair(std::ref(str1), std::ref(str2))); could help, but unfortunately no, this still produces string copies.
map.find(std::make_pair(std::move(str1), std::move(str2)) should work but let's assume that these strings (str1, str2) are const or should not be moved.
So I'm asking whether there is any other way to do a the map search without making redundant string copies?
(Note that using std::string_view for the std::map key is NOT an option since the map should own its strings.)
C++14 added the following overload for
std::map::findwhich allows transparent search:To make use of this, you still need the
std::mapto have a suitable comparator:This
pair_lessis totally transparent. It can directly comparestd::pair<X, Y>tostd::pair<const X&, const Y&>.Note on
std::pair::operator<The C++ standard requires
std::pair::operator<to be transparent since LWG Defect 3865. Theoretically, this would makestd::less<void>orstd::ranges::lesssufficient as a transparent comparator.However, libstdc++ does not yet implement transparent
std::paircomparisons at the time of writing, sostd::less<void>would only work for compilers other than GCC.Proper C++20 constraints
Properly constraining the call operator of
pair_lessis not so easy. It's not strictly necessary anyway, but moves the error to the call site of the operator and may be better for diagnostics.The usual approach would be something along the lines of
See also
boolean-testable.