The standard \"map\" containers in C++ allow you to insert an rvalue:
T x;
std::map m;
// m[1]; // populate \"1\"
auto it = m.insert(std::m
Though std::move does not actually perform any move, and neither does std::make_pair, std::make_pair forwards its arguments to the std::pair constructor, which initialises its two value members from those arguments.
As such, the move is performed at that point, before the std::map has a chance to do anything. So, yes, you end up with a "broken" move for no good reason.
You should be able to take advantage of emplace (in order to skip the pair construction). From Table 102:
Effects: Inserts a
Tobjecttconstructed withstd::forwardif and only if there is no element in the container with key equivalent to the key of(args)... t.
Clearly, the library is still "forwarding" at this point so it's pre-move, and in your case no emplace shall take place so the entire expression ought to be an effective no-op.
However, libstdc++ from GCC 4.8.0 appears to have a bug in this regard: emplace invokes _M_emplace_unique on the internal tree, which forwards the arguments to _M_create_node, which forwards the arguments to allocator_traits<_Node_allocator>::construct, which forwards the arguments to _S_construct, which forwards the arguments to __a.construct which, with the default allocator, is std::allocator, which is the pair constructor you were trying to avoid... all before the collision check in _M_emplace_unique.
It could be claimed that the standard is ambiguous in this regard, but I'd call it a violation of intent. Then again, clang v3.4 with libc++ exhibits this behaviour too, as does Visual Studio 2012. So if my standard interpretation is correct, this fails on all three of the mainstream toolchains.
I guess they all decided that the "if and only if" applied to the insertion, rather than the insertion and the construction.
I have posted a question on std-discussion aiming to provoke an improvement to the passage from Table 102 to authoritatively answer this once and for all.