
Dave,
However, for move semantics (and what could be more suited to that than a UUID?) the invariant often needs to include a "empty" moved-from state anyway, and you could argue that one might as well implement a cheap, non-throwing default ctor that produces that state. The argument I sometimes use against it is that even though the empty state technically becomes part of the class invariant, limiting that state to moved-from objects still offers some improved ability to reason about code... but that's a weaker argument than I'd like.
I just read "n2027: A Brief Introduction to Rvalue References" (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html) and there the move is done manually: // move semantics clone_ptr(clone_ptr&& p) : ptr(p.ptr) {p.ptr = 0;} That is, we manually take a resource (ptr) from the source (p), assign the resource to the target (this) and re-assign the target resource (p.ptr = 0). Therefore, I am glad to see that there seems *no* requirement to provide some special "empty" state and hijack the default constructor for the purpose -- it's up to the implementer to decide which state satisfy the need. Taking the discussed uuid as an example that might look like the following: uuid(uuid&& p) : data_(p.data_) { p = uuid::nil(); } or uuid(uuid&& p) { *this = uuid::nil(); std::swap(*this, p); } So, we seem to be safe and sound with the uuid default constructor (or lack of it) unaffected and irrelevant. Does it make sense? Best, V.