1

Since emplace_hint method of set / map returns only an iterator figuring out whether item has been actually added is not as convenient as when using emplace or insert. Right now I just get container size before / after and compare them:

::std::map<int, int> items{};
const auto initial_items_count{items.size()};
const auto it_item{items.emplace_hint(items.begin(), 0, 5)};
if(items.size() != initial_items_count)
{
    // perform additional actions...
}

It can be wrapped up into a helper returning pair, but maybe there is an existing simpler approach?

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • I imagine the idea is that one would normally couple `emplace_hint` with the result of `lower_bound`. So that information is available before the act. Otherwise `emplace_hint` is not guaranteed better than a regular `emplace`. – StoryTeller - Unslander Monica Dec 23 '17 at 21:40
  • 1
    The `lower_bound` trick is a good approach for containers of PODs. For containers of classes, one could always have an extra parameter to the constructor, a `bool &`, that the constructor sets; so when `emplace_hint` returns, checking what's in the `bool` tells you if an object was constructed. – Sam Varshavchik Dec 23 '17 at 21:47
  • @StoryTeller In my situation values being inserted are mostly monotonically decreasing but with considerable amount of values that will still go somewhere in the middle. Also these values are somewhat heavy so I've just decided to keep code simple and just always supply `begin` as hint (which does increase performance compared to `emplace` even though it not always optimal). – user7860670 Dec 23 '17 at 22:12
  • @SamVarshavchik Isn't emplacing into `set` always construct an item? Also this approach would still require to define an extra local variable of `bool` type. – user7860670 Dec 23 '17 at 22:24
  • Not, as you pointed out, if the set item already exists. – Sam Varshavchik Dec 23 '17 at 22:41

1 Answers1

1

Given that map::size is O(1) (per the standard) I believe this approach (especially with a helper that mimics map::emplace's return) is reasonable.

Quentin
  • 62,093
  • 7
  • 131
  • 191
SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • You see, adding such a small standalone wrapper would be just about the same amount of bother than doing without it. It will help to get rid of an extra temporary variable but in exchange I will get an extra include and some extra bother with dependency management. This actually is not a big issue, but I've noticed that I wrote the similar code several times already and suspected that I might be doing something not as efficient as it could be done. – user7860670 Dec 23 '17 at 22:19