At what point does the :: emplace map create an object?

Is the point at which std::map::emplace creates an object (i.e. calls a constructor) somehow defined in the standard? If so, will such a key occur before or after?

This is of great importance in the following cases:

 struct X {}; std::map<int, std::unique_ptr<X> > map; void f(int x) { map.emplace(x, new X); } 

If the object is created first, everything is cool (unique_ptr is designed and owns the resource), but if it is created after verification, a memory leak occurs in the event of a duplicate key.

Everything I could find in the Standard

Inserts a value_type t object constructed with std::forward<Args>(args)... if and only if the element does not have an element with a container with a key equivalent to t.

which does not address the question that I have.

+8
c ++ language-lawyer c ++ 11
source share
1 answer

This is really unproven, which is partly due to the fact that C ++ 17 added try_emplace to mute the semantics. N3873 , an earlier version of the try_emplace , discusses the existing wording well.

In general, it should be β€œbefore,” since β€œafter” is not feasible, and the standard would be defective if it imposed such a requirement. Consider emplace(piecewise_construct, forward_as_tuple(foo, bar), forward_as_tuple(meow, purr)) . Since the key and value do not have to be movable, you pretty much need to first build the object and check for the existence of the key secondly, because you cannot check for the existence of the key without the key.

It is possible, however, that the implementation may require a special case of emplace(key_type, something) ; this is usually a good thing to not pay for the required distribution + construction + destruction + release when the key exists.

+12
source share

All Articles