
Howard Hinnant wrote:
On Dec 18, 2008, at 10:22 AM, Chris Newbold wrote:
In the end, I concluded that emulation on C++03 could provide move semantics, but that move operations need to be explicit, not implicit. That is, the test case should be:
void f() { unique_ptr<int> p1(new int); unique_ptr<int> p2(move(p1)) }
Is my conclusion correct?
Your conclusion is correct. And this is not a problem. moves from lvalues (p1) should be explicit, even in C++0X. Here the emulation is perfect.
Note that if p1 is an rvalue, the move is implicit, both emulated and in C++0X:
unique_ptr<int> g();
void f() { unique_ptr<int> p2(g()); // implicit move, good }
One place the emulation breaks down is inside of g():
unique_ptr<int> g() { unique_ptr<int> p; // ... return move(p); // ! explicit move necessary for emulation, unwanted in C++0X }
Another currently weak place in the emulation is that "move" is injected as a friend of the move-only class. In C++0X, move is a std::lib function, not to be implemented by user code. And user code should always call std::move(x), not move(x).
Another weakness - at least in my implementation - is that implicit conversions on return don't work. This is not a problem for unique_ptr, really, but it is for my more complex pointers. OwningStmtResult foo() { return true; // OwningStmtResult has an implicit conversion from bool. } This fails to compile. Sebastian