
On Sep 7, 2009, at 6:03 PM, David Abrahams wrote:
on Mon Sep 07 2009, "Peter Dimov" <pdimov-AT-pdimov.com> wrote:
Rationale: The move assignment operator should be fast enough that an extra if- test may adversely impact performance (above the noise level).
The problem with making it UB is that y = move(x) now needs to be guarded with if( &x != &y ) everywhere in client code. Sometimes the user will know that x is not y, but is this really the case most of the time?
Most of the time, yeah. Definitely, in most of the generic algorithms. But I'm not sure whether it's true enough of the time. Consider our new generic std::swap:
template <class T> void swap(T& x, T& y) { T z = std::move(x); x = std::move(y); // <== uh oh? y = std::move(z); }
Do we think swap(x,y) is also an error when x == y?
This is a decent argument to not assert in self-move-assignment. But this is also almost certainly harmless: #include <algorithm> #include <iostream> class A { int data_; public: explicit A(int data = 0) : data_(data) {} A(A&& a) : data_(a.data_) {a.data_ = 0;} A& operator=(A&& a) {data_ = a.data_; a.data_ = 0; return *this;} friend std::ostream& operator<<(std::ostream& os, const A& a) { return os << a.data_; } }; int main() { A a(5); std::cout << "Before swap a = " << a << '\n'; std::swap(a, a); std::cout << "After swap a = " << a << '\n'; } Before swap a = 5 After swap a = 5 But if I caught my own code doing a self-swap, yeah, I would treat it as a bug and correct it. For example, every time I've written reverse (which does nothing but swap x and y while x and y move closer to each other in the sequence), I'm careful to break out of the loop before &x == &y. -Howard