I have some code that adds to a std::vector and a std::map after creating an object.
v.push_back(object); // std::vector
m[object->id] = object; // std::map
I want to make this have a strong exception guarantee. Normally, to make operations like these atomic, I would implement a swap method for each container, and call all of the functions that could throw on temporary copies of the container:
vector temp_v(v);
map temp_map(m);
temp_v.push_back(object);
temp_m[object->id] = object;
// The swap operations are no-throw
swap(temp_v, v)
swap(temp_m, m)
However, making temporary copies of the entire vector and map seems very expensive. Is there any way to implement a strong exception guarantee for this function without the expensive copies?
General Case
Technically, only one copy is required:
Another option is catch-roll-back-and-rethrow:
Or the other way around. I picked this order because the
vector::pop_back()is guaranteed not to fail.UPDATE: If object->id could be present, see Grizzly’s answer for a solution.
Specific Case for Pointers
However, as you are using
object->, you might be storing pointers. The copy-constructor of a pointer cannot throw, and we can use that fact to simplify the code:And if you are really worried about frequent resizing: