README Container Design, Step 3 --------------------------------------------------------------------------------- From Step 2 we have exception-safe and exception-neutral versions of special member functions for initializing, copying, moving, and destroying Container objects. Here we have added clear() and swap() functions, the latter in both a member and a non-member version. The non-member overloading will be a better match for Containers than the generic std::swap(). We use these functions to simplify the implementation of the move constructors, the copy assignment operator, and the move assignment operator. The member swap is implemented using the standard library swap: template void Container:: swap(Container& other) nothrow { std::swap(elems_, other.elems_); std::swap(capacity_ , other.capacity_); std::swap(size_ , other.size_); } The standard library swap guarantees not to throw, if the the argument type, T, is nothrow move constructible and nothrow move assignable. Here we swap pointers and their "copy constructor" and "copy assignment operator" cannot throw, so the member swap fulfills the nothrow guarantee. The non-member swap is implemented using the member swap so also this swap fulfills the nothrow guarantee: template void swap(Container& a, Container& b) nothrow { a.swap(b); } The copy assignment operator is implemented using the "create a temporary and swap" idiom (the self test can be excluded): template Container& Container:: operator=(const Container& other) { if (this != &other) { Container(other).swap(*this); } return *this; } The only possible exception is from the copy constructor, which is fail-safe. The move constructor lets the destination container be initialized according to the initializers declared in the data member declarations, an empty container is created, and then swaps content with the other object. Nothing here can fail: template Container:: Container(Container&& other) { swap(other); } The move assignment operator first clears the left hand side container, making it an empty container, and then swaps content with the right hand side container. Nothing here can fail: template Container& Container:: operator=(Container&& other) { if (this != &other) { clear(); swap(other); } return *this; } So, we are still exception-safe and exception-neutral, and by adding clear() and swap() we have made it possible to hide the details and reuse code in a nice way. Still robust! ---------------------------------------------------------------------------------