
DE wrote:
how do i make a function return an object by value and other object to, say, move assign from that returned object within current C++ std? i.e.
my_type foo() {/*...*/} //... my_type a; a = foo(); //move assignment is intended here
-- Pavel
Fortunately, you don't have to worry about the return type of foo; just return by value, as you normally would. Return Value Optimization (RVO) (or whatever mechanism you want to attribute this to) takes care of eliding the copy between the "return" in foo and the call site. So now you just need to worry about which operator= the assignment will call. Currently, I believe, if you use the move-enabling macros in Boost.Move, then the move assignment operator of my_type will be chosen for the assignment operation, rather than the copy assignment operator. The "trick" that Boost.Move employs is to declare the copy assignment operators as operator=(T&) and operator=(const rv<T>&); and the move assignment operator as operator=(rv<T>&). The end result is that rvalues of type T bind to the move assignment operator, while all lvalues will bind to one of the copy assignment operators. Thus, the above assignment, "a = foo()", will move assign. There has been some discussion, however, that this mechanism has undesirable side effects, one of which is the "poisoning" of the auto-generated copy assignment operator for all classes that enclose a class (inheritance or member object) that use a move-enabling macro. The auto-generated copy assignment operator will take its parameter by reference to non-const, which is Bad. The alternative is, for move-enabled classes, to write a single assignment operator accepting its parameter by value. This is safe, specifically addressing the above "poisoning" problem, if non-optimal for classes with member objects for which copying and moving is identical. I've actually experimented with different alternatives to the move-enabling macros (as well as how to implement forwarding), and at some point soon will present my thoughts to Ion on what I think could be done. - Jeff