Matteo Settenvini <mat...@member.fsf.org> writes: > Murray Cumming <murr...@murrayc.com> writes: > >> And, should we implement swap() using std::swap() on the member >> variables, or even std::move() on the member variables? > > It depends. If everything is noexcept, I'd say it's quite the same. If > something can throw an exception, it needs to be done by e.g. swapping > tuples, so that it is guaranteed that the object is not left in an > inconsistent state. For instance, this is dangerous [1]: > > void C::swap(C& that) > { > using std::swap; // needed to allow Koenig lookup rules to apply > swap(this->a, that.a); > swap(this->b, that.b); // throws > swap(this->c, that.c); > } > > Then when catching the exception, "this" and "that" will have had their > first member swapped, but not the other two fields. >
I wanted to follow up my previous post with a simpler solution using variadic templates. This makes relatively easy to implement a safer version of swap with rollback semantics. Code follows. Cheers, Matteo #include <exception> #include <iostream> #include <tuple> #include <utility> inline void safer_swap () { return; } template<typename T, typename... Rest> inline void safer_swap (T& a, T& b, Rest... cdr) { using std::swap; swap (a, b); try { safer_swap (cdr...); } catch (...) { swap (a, b); throw; } } namespace ns { class Throwing { public: Throwing() = default; Throwing(const Throwing&) { throw std::runtime_error(""); } }; class Swapper { public: int a; Throwing b; int c; void swap(Swapper& that) { safer_swap (a, that.a, b, that.b, c, that.c); } }; } // ~ namespace ns; namespace std { template<> void swap(::ns::Swapper& a, ::ns::Swapper& b) noexcept(noexcept(a.swap(b))) { a.swap(b); } } int main() { ns::Swapper a, b; a.a = a.c = 1; b.a = b.c = 2; try { std::swap(a, b); } catch(std::runtime_error&) { std::cout << "(" << a.a << ", " << a.c << ") vs. " << "(" << b.a << ", " << b.c << ")" << std::endl; } } _______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtkmm-list