Topic: x = f(move(x))


Author: Joe Gottman <josephgottman@comcast.net>
Date: Thu, 8 Sep 2011 14:47:01 -0700 (PDT)
Raw View
Suppose I have the following pair of functions:

string foo(const string &x); // Makes a copy of x, modifies, and returns it.

string foo(string &&x) // Modifies and returns x itself, since x is an rvalue.

Given these functions, does the following code work?

int main()
{
  string x = "hello";
  x = foo(move(x));
  return 0;
}

I think it doesn't, because a move-constructor or move-assignment
operator might modify its input parameter, but I'm not sure.

Of course, one way around this problem is to replace the line
x = foo(move(x)) with the two lines

string temp = move(x);
x = f(move(temp));

This would work, but it is slightly unwieldy, requiring a temporary
variable and two calls to move.  It would be nice if there were a
library function to do this for us:

template <class T>
T inplace_move(T&& x) {return move(x);}

Then the single line
x = foo(inplace_move(x));

would move x to a temporary variable, call foo on that temporary
variable, then move the temporary variable back to x.

Joe Gottman


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sat, 10 Sep 2011 00:30:17 -0700 (PDT)
Raw View
On 2011-09-08 23:47, Joe Gottman wrote:
>
> Suppose I have the following pair of functions:
>
> string foo(const string &x); // Makes a copy of x, modifies, and returns
> it.
>
> string foo(string &&x) // Modifies and returns x itself, since x is an
> rvalue.
>
> Given these functions, does the following code work?
>
> int main()
> {
> string x = "hello";
> x = foo(move(x));
> return 0;
> }

I believe this should work because of the sequencing rules.

> I think it doesn't, because a move-constructor or move-assignment
> operator might modify its input parameter, but I'm not sure.

As of C++11 there has been added special wording to "5.17 Assignment
and compound assignment operators [expr.ass]":

"In all cases, the assignment is sequenced after the value
computation of the right and left operands, and before the value
computation of the assignment expression."

HTH & Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: SG <s.gesemann@gmail.com>
Date: Sat, 10 Sep 2011 00:30:47 -0700 (PDT)
Raw View
On 8 Sep., 23:47, Joe Gottman wrote:
>
> Suppose I have the following pair of functions:
>
>   string foo(const string &x); // Makes a copy of x, modifies, and returns it.
>   string foo(string &&x) // Modifies and returns x itself, since x is an rvalue.
>
> Given these functions, does the following code work?
>
>   int main()
>   {
>     string x = "hello";
>     x = foo(move(x));
>     return 0;
>   }

Yes. foo(move(x)) refers to some other temporary object. At this time,
x will be "empty" but it does not matter. x is still assignable.

> Of course, one way around this problem is to replace the line
>   x = foo(move(x))
> with the two lines
>   string temp = move(x);
>   x = f(move(temp));
>
> This would work, but it is slightly unwieldy, requiring a temporary
> variable and two calls to move.  It would be nice if there were a
> library function [...]

Let me stop you right there. As I said, there is no problem with your
1st code example. But I would like to suggest an alternative:

  string foo(string x) {  // no other overloads needed!
     std::reverse(x.begin(),x.end());
     return x;
  }
  :
  string z = ...;
  z = foo(move(z)); // x and foo(move(z)) will be move-constructed
automatically

The nice thing about move-enabled classes is that you don't need to
sprinkle rvalue references all over the place. x in foo and the
function's return value will automatically be move-constructed. Pass-
by-value should become more fashionable again in my opinion. Be sure
to check out Dave's "Want Speed? Pass by value!" article:
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

Cheers!
SG


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]