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