Answer to
@Cubbi is correct, but does not explain why this was done.
Traditionally, arguments are accepted by const& if they are not inline, so one would expect:
insert(key_type const&, value*)
Which naturally allows:
someMap.insert("abc", new DerivedAction());
But the authors chose a signature:
insert(key_type&, value*)
And yes, this is intentional .
The problem is that it is expected that a form using a raw pointer will be used with the built-in new , as you demonstrated in your own example, however there is a security issue with exceptions.
You can read how Sutter will take him to Guru of the Week .
When a function is called in C ++, all its arguments must be evaluated before the call starts, and the order in which the arguments are evaluated is unspecified. Therefore, there is a risk if evaluating the arguments performs memory allocation and another operation (which may throw). In your example:
insert("abc", new DerivedAction()); // equivalent to insert(std::string("abc"), new DerivedAction());
Before making a call, two operations can be performed (in an unspecified order):
- converting
"abc" to std::string - building
DerivedAction object in free storage
If the conversion "abc" to std::string thrown out and it was scheduled after memory allocation, then a memory leak occurs because you have no way to free it.
By making the first argument NOT be temporary, they prevented this error. This is not enough (in general), since any function call can be executed and still throw, but it makes you think, right?)
Note: the version that uses auto_ptr by reference does the opposite, they force you to preallocate memory, so the "abc" conversion may throw, no longer take risks, because RAII will provide the proper cleanup