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
T
objectt
constructed withstd::forward<Args>(args)...
if and only if there is no element in the container with key equivalent to the key oft
.
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<std::pair<const _Key, _Tp> >::construct
, 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.