Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try_emplace in std::unordered_map without constructing temporary Key

If transparent hash and key comparison functions are used with std::unordered_map, its find has since C++20 had an overload that allows calling the function without constructing an instance of the key. However, try_emplace does not currently have such an overload, so my understanding is that an instance of Key is always constructed when the function is called.

Is there any way to replicate this behaviour of find in a function that works somewhat like try_emplace or operator[]? In other words, I would like to retrieve the old value if one exists, or emplace a new value. I could just use a combination of find and emplace but I’m guessing that emplace does some unnecessary work in this case. If I had first determined a candidate location, I could pass it to emplace_hint (like with lower_bound when using std::map), but I don’t know how to get a suitable iterator when using std::unordered_map.

like image 932
tsnorri Avatar asked Oct 15 '25 23:10

tsnorri


1 Answers

The most efficient way to emulate the try_emplace() member function in the std::unordered_map container for heterogeneous lookup involves a combination of both the find() and emplace() member functions.

Example:

template <typename K, typename ...Args>
std::pair<iterator, bool> try_emplace(K&& k, Args&& ...args)
{
  std::pair<iterator, bool> p{this->find(k), false};
  
  if (p.first == this->end()) {
    p = this->emplace(std::forward<K>(k), std::forward<Args>(args)...);
  }
  
  return p;
}

Indeed, the use of the emplace_hint() member function to exploit the already-existing iterator does not determine any performance improvement, since all the major implementations (MSVC, libc++, libstdc++) do not consider the "hint".

like image 50
LoS Avatar answered Oct 18 '25 15:10

LoS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!