Does map move-insertion guarantee that elements are or are not moved from?

后端 未结 1 614
慢半拍i
慢半拍i 2020-12-15 09:46

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         


        
相关标签:
1条回答
  • 2020-12-15 10:25

    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 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.

    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.

    0 讨论(0)
提交回复
热议问题