Gottlob Frege wrote:
It just means I need to double buffer higher up. I really want my drawing program to just fail (rollback) the transaction if it can't complete - that is what users really want.
That's true, I understand that, and I tried to communicate the need for variant to support the strong guarantee on assignment for this reason. Normally, if your type was, say, vector<>, you don't need all vectors to be double-buffered. You do vector<> tmp( v ); process( tmp ); v.swap( tmp ); // commit transaction at the places where you want the strong guarantee. The problem with variant<> is that the above doesn't quite produce the strong guarantee when the types aren't nothrow move constructible. I also tried to provide a solution to this problem in the form of pilfering, because types can typically be pilfered even when they can't be nothrow-moved-from, but this didn't go anywhere.