map::emplace with multiple parameter constructor ?

The Partridge Family were neither partridges nor a family. Discuss.
albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: map::emplace with multiple parameter constructor ?

Post by albinopapa » May 21st, 2020, 3:46 am

Slidy wrote:
May 20th, 2020, 5:33 pm
Doesn'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.
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.

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.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: map::emplace with multiple parameter constructor ?

Post by albinopapa » May 21st, 2020, 3:49 am

binbinhfr wrote:
May 20th, 2020, 7:52 pm
@albi: you like to play with the theory, uh ? are you a professional programmer, or maybe working on the computer research side ?
I'm not a professional programmer, and the only research is for personal use.

I learn through experimentation, debugging and looking through other developers' code. The C++ standard library for instance to see how something could be done. This is how I am learning how to use templates.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Slidy
Posts: 80
Joined: September 9th, 2017, 1:19 pm

Re: map::emplace with multiple parameter constructor ?

Post by Slidy » May 21st, 2020, 1:50 pm

The pair itself is constructed in place, the thing in the pair is not. The A object in your scenario would be placed into the pair via move (or copy if a move doesn't exist). I doubt this is an expensive operation, and as I mentioned before if it is then you should store pointers and perform dynamic allocation.

Post Reply