Reference: http://stackoverflow.com/q/20328242/560648
Considering the following:
#include <memory>
#include <utility>
#include <map>
#include <iostream>
#include <cassert>
int main()
{
typedef std::unique_ptr<int> T;
T x(new int(1)), y(new int(2));
std::map<int, T> m;
m.emplace(1, std::move(x));
auto it = m.emplace(1, std::move(y));
assert(!it.second);
std::cout << y.get() << '\n';
}
The result is "0"; that is, y has been moved into the container even though this occurred during an "emplace" operation that ultimately resulted in no modification to the container (since key 1 already existed).
Table 102 says about emplace:
Effects: Inserts a T object t constructed with std::forward<Args>(args)... if and only if there is no element in the container with key equivalent to the key of t.
So, I would not have expected this move. I would have expected the argument to be untouched since there is already an element in the container with key equivalent to the key of t. But, instead, GCC 4.8.0, clang v3.2 and MSVS 2012 all result in y becoming null.
- Is this the intent of the passage? Or wouldn't be clearer if the node construction only occurred if destined for insertion? Then the moved-from object would remain intact and untouched when no insertion is performed.
- Yes or no, could the passage be disambiguated to define whether or not the construction happens in this scenario, as well as defining whether the insertion happens?
Thanks,
Tom