Examples
Team LiB
Previous Section Next Section

Examples

Example 1: Retry after failure. If your program includes a command for saving data to a file and the write fails, make sure you revert to a state where the caller can retry the operation. In particular, don't release any data structure before data has been safely flushed to disk. For example, one text editor we know of didn't allow changing the file name to save to after a write error, which is a suboptimal state for further recovery.

Example 2: Skins. If you write a skinnable application, don't destroy the existing skin before attempting to load a new one. If loading the new skin fails, your application might end up in an unusable state.

Example 3: std::vector::insert. Because a vector<T>'s internal storage is contiguous, inserting an element into the middle requires shuffling some existing values over by one position to make room for the new element. The shuffling is done using T::T(const T&) and T::operator=, and if either of those two operations can fail (by throwing an exception), the only way to make insert provide the strong guarantee is to make a complete copy of the container, perform the operation on the copy, and, if successful, swap the original's and copy's state using the no-fail vector<T>::swap.

But if that were done every time by insert itself, every caller of vector::insert would always incur the space and performance penalty of making a complete copy of the container, whether it needed the strong guarantee or not. That is needlessly expensive. Instead, those callers who do want the strong guarantee can do the work themselves, and are given sufficient tools for doing so. (In the best case: Arrange for the contained type to not throw from its copy constructor or copy assignment operators. In the worst case: Take a copy, insert into the copy, and swap the copy with the original when successful.)

Example 4: Unlaunching a satellite. Consider a function f that as part of its work launches a satellite, and the LaunchSatellite function it uses provides the strong or no-fail guarantee. If f can perform all of its work that could fail before launching the satellite, f can be coded to provide the strong guarantee. But if f must perform other operations that might fail after having already performed the launch, it cannot provide the strong guarantee because it cannot bring the satellite back. (At any rate, such an f probably ought to be split into two functions, because a single function should probably not be trying to do multiple pieces of work of such significance; see Item 5.)

    Team LiB
    Previous Section Next Section