Consider the following:
std::vector<std::unique_ptr<int>> ptrsToInts;
ptrsToInts.emplace_back(new int);
If reallocation occurs in the vector, and that fails (throwing std::bad_alloc
), am I "safe" or will I leak an int
?
C++11 23.3.6.5 [vector.modifiers]/1 says:
If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of
T
or by anyInputIterator
operation there are no effects.
which seems to indicate that this is a potential problem. That is, if there are "no effects", then no unique_ptr
ever was constructed, and therefore the destructor behavior one would rely on to delete
that pointer would not occur. (Which might indicate that emplace_back
should be banned for containers of unique_ptr
s)
Specific use case for emplace_back : If you need to create a temporary object which will then be pushed into a container, use emplace_back instead of push_back . It will create the object in-place within the container.
Calling emplace_back will call the move constructor of std::string when std::move is used, which could save on a copy (so long as that string isn't stored in a SSO buffer). Note that this is essentially the same as push_back in this case.
If reallocation is required and it fails, then yes, your object never went into the container and will thus be lost.
However, it should be noted that this is pure user error. emplace_back
should not be "banned" for containers of unique_ptr
, because there are perfectly safe ways of doing this (such as reserve
ing the space beforehand, so you know it will always be there). Also, you can pass in whole unique_ptr
s, since it's perfectly capable of using a move constructor.
So really, it's your fault for not properly wrapping your non-RAII object (the int*
) in a RAII object before the point where you could throw exceptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With