Move semantics only help with classes with that have non-stack allocated resources like pointers. Basically, a move is a shallow copy with the guarantee that the resource won't be deleted or freed by the destruction of the doner object.Slidy wrote: ↑May 20th, 2020, 5:33 pmDoesn't the emplace function perform a move? Don't think there are any copies performed here. If you think a move is still expensive for your object you could always store a pointer (preferably unique_ptr) rather than the object itself, then construct the object using new.
In other words nothing is gained by a move to a struct with only stack allocated members. Look at std::array where all the elements are allocated on stack. You can try std::move( arr ), but unless it's an array of all pointers, you'll still get a copy.
For moves to be efficient, you'd need more elements stored on the heap than elements stored on the stack.
As far as binbin's issue, emplace calls std::pair's constructor with the arguments passed in. Since his pair is <int, A>, it's only expecting to have an ( int, A ) passed to it to be forwarded to std::pair constructor. The pair itself is constructed in place in the newly heap allocated memory. So, if emplace( 12, A{ 1, 2 } ) is used, what is forwarded to std::pair<int, A> is ( int&&, A&& ) or two rvalue references. 12 is an rvalue reference because it can't be assigned to and the A{ 1, 2 } is an rvalue reference because it's a temporary. This temporary if holding nothing but stack allocated objects is then copied into the heap allocated memory that was allocated by multimap::emplace. Same with the 12 for the key, the value 12 is stored as a temporary probably in a register then copied to the allocated space for the pair.
As I stated previously though, you can only hope for some sort of copy/move elision. Which means that those two temporaries made were actually created directly to the spots in memory where they were going to be assigned instead of temporaries in registers then copy/moved into memory. I don't know how far the optimizer can work or if it's even "legal C++" to go that far.