According to cppreference, both std::set
and std::map
emplace
functions return a std::pair<iterator,bool>
, with a bool
value to say if the insertion actually took place.
However, emplace_hint
returns an iterator
either to the inserted element or to the existing element in the set or map if the insertion didn't happen. There is no bool
value here.
Is there any reason for this difference in the interface of these similar functions?
Update
Function insert
returns the bool
value only when no hint is provided. This is consistent with the behavior of emplace
and emplace_hint
. The question is then: is there any reason to not return a bool
when a hint is given?
I can only think that maybe there is some performance reason, because the user usually provides a hint after a lower_bound
/upper_bound
operation, so it's sure the insertion will happen.
Return Value: The function returns a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element with an equivalent key in the map.
The standard solution to insert new elements into a map is using the std::map::insert function. It inserts the specified key-value pair into the map only if the key already doesn't exist. If the key already exists in the map, the element is not inserted.
int a=10,b=20; map < pair < int,int >, int > m; pair < int,int >numbers = make_pair(a,b); int sum=a+b; m[numbers]=sum; Our map will have its key as pairs of numbers. We can access the integer values of pair variable using dot(.) operator.
insert() doesn't overwrite.
emplace_hint
does that likely for consistency with the hinted insert
: emplace
was initially proposed as a pair of overloads, mirroring insert
, but the hinted overload was renamed after LWG 763, although Josuttis wanted to rename the non-hinted version instead)
The hinted insert
for associative containers takes an iterator and a value and returns an iterator in order to be compatible with the regular insert
on sequential containers in generic code. as mentioned in Josuttis's book. This compatibility is exploited by std::inserter
The easiest way to determine, whether the emplace took place or not, is to store the size()
of the map in a variable and test, whether that size has increased after the emplace_hint()
:
auto oldsz = myMap.size();
myMap.emplace_hint(it, args...);
if(myMap.size() > oldsz) {
// emplace was accepted
} else {
// the emplace was rejected, as it would have overwritten an element
}
The same code can also be used with insert_or_assign()
, if the new value shall overwrite the old in case of an already existing key.
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