Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::move() function

39 views
Skip to first unread message

Doug Mika

unread,
May 7, 2015, 5:08:44 PM5/7/15
to
I'm kind of curious when it would be an advantage to use std::move. I know it turns an lvalue to an rvalue, but not much else. When would it be adventagous to use std::move?

I included a short program below, can I use y after calling test, or is there no guarantee as to its integrity after I employ std::move on it?

#include <iostream>
#include <string>
#include <map>
#include <functional>

using namespace std;

void test(int&& x){
//do something with x
}

int main(int argc, char** argv) {
//The Program
int y=5;
test(move(y));

//after my code returns from test() should I avoid using y?)
...
return 0;
}

Bo Persson

unread,
May 8, 2015, 11:39:37 AM5/8/15
to
On 2015-05-07 23:08, Doug Mika wrote:
> I'm kind of curious when it would be an advantage to use std::move. I know it turns an lvalue to an rvalue, but not much else. When would it be adventagous to use std::move?

Whenever you need an lvalue turned into an rvalue. :-)

>
> I included a short program below, can I use y after calling test, or is there no guarantee as to its integrity after I employ std::move on it?
>
> #include <iostream>
> #include <string>
> #include <map>
> #include <functional>
>
> using namespace std;
>
> void test(int&& x){
> //do something with x
> }
>
> int main(int argc, char** argv) {
> //The Program
> int y=5;
> test(move(y));
>
> //after my code returns from test() should I avoid using y?)

Of course, that depends on what test() does to the object.

Standard library types are guaranteed to be in "a valid but inspecified
state" after being moved from. User defined types are in whatever state
their move constructor or move assignment leave them in.

Generally, you use std::move(y) to give the value away. After that you
should be able to destroy y (like when going out of scope) or assign it
a new value. That's about it.


Bo Persson





Doug Mika

unread,
May 8, 2015, 11:51:30 AM5/8/15
to
Here I have another two short extracts from a document I was reading. The first is:

vector<String> vs;
String s(15);
vs.push_back(s); //uses String's copy constructor

does this use String's copy constructor because it uses the void push_back (const value_type& val); method which inside of it copies the string passed as reference into the vector vs?

Also, here is another short code extract:

vector<String> vs;
String s1(15), s2(20);
vs.push_back(static_cast<String&&>(s1)); //uses String's move constructor
vs.push_back(std::move(s2)); //uses String's move constructor

Does this use String's move constructor because inside the overwritten push_back method which is void push_back (value_type&& val); the method inside guarantees the implementation of the string's move constructor and not the copy constructor?

Victor Bazarov

unread,
May 8, 2015, 12:19:15 PM5/8/15
to
On 5/8/2015 11:51 AM, Doug Mika wrote:
> Here I have another two short extracts from a document I was reading. The first is:
>
> vector<String> vs;
> String s(15);
> vs.push_back(s); //uses String's copy constructor
>
> does this use String's copy constructor because it uses the void
push_back (const value_type& val); method which inside of it copies the
string passed as reference into the vector vs?

Yes.

> Also, here is another short code extract:
>
> vector<String> vs;
> String s1(15), s2(20);
> vs.push_back(static_cast<String&&>(s1)); //uses String's move constructor
> vs.push_back(std::move(s2)); //uses String's move constructor
>
> Does this use String's move constructor because inside the
> overwritten push_back method which is void push_back (value_type&&
> val); the method inside guarantees the implementation of the string's
> move constructor and not the copy constructor?

Too many words for me to understand, honestly. "The method inside
guarantees.."? There are two overloaded 'push_back' member functions,
one takes a prvalue (a ref to const lvalue) just like it did in 1998,
and the other that takes an xvalue (an rvalue ref), which is new in
C++11. *Both* create the element by constructing it, so essentially
their code ought to be identical. However, due to the existence of
overloaded constructors in the element type (std::string in this case),
the two 'push_back' functions will use different c-tors, the copy c-tor
in the case of the old 'push_back' and the move c-tor in the case of the
newer 'push_back'.

V
--
I do not respond to top-posted replies, please don't ask

Paavo Helde

unread,
May 8, 2015, 12:51:31 PM5/8/15
to
Doug Mika <doug...@gmail.com> wrote in
news:8f201778-8190-4960...@googlegroups.com:

> Here I have another two short extracts from a document I was reading.
> The first is:
>
> vector<String> vs;
> String s(15);
> vs.push_back(s); //uses String's copy constructor
>
> does this use String's copy constructor because it uses the void
> push_back (const value_type& val); method which inside of it copies
> the string passed as reference into the vector vs?

Yes, as s is a lvalue (it has a name and can be assigned to) this is
passed to the const reference overload. A conforming std::vector
implementation will finally copy the value to inside the vector by using
the copy constructor. Some other evil container class could use std::move
() inside and move away the value instead, but std::vector would not do
that.

Well, if the compiler notices that s is not accessed afterwards then it
is allowed to optimize away the copy constructor call and construct the
value directly in the correct place.

>
> Also, here is another short code extract:
>
> vector<String> vs;
> String s1(15), s2(20);
> vs.push_back(static_cast<String&&>(s1)); //uses String's move
> constructor
> vs.push_back(std::move(s2)); //uses String's move
> constructor
>
> Does this use String's move constructor because inside the overwritten
> push_back method which is void push_back (value_type&& val); the
> method inside guarantees the implementation of the string's move
> constructor and not the copy constructor?

These examples are basically identical. Yes, if String has a move
constructor this ought to be used here by a conformant std::vector
implementation. I cannot find the guarantee in the standard text right
now, but this is at least the intended behavior.

hth
Paavo

Doug Mika

unread,
May 8, 2015, 1:21:13 PM5/8/15
to
If I have a short function called from main that returns an object t of type T by value, would the compiler below know to move the value t if it goes out of scope, or would it copy it upon return?

T someFunc(){
T t;
//do something
return t; //would this t be returned via move semantics?
}

or if the compiler wouldn't know, should I write:

T someFunc(){
T t;
//do something
return std::move(t); //explicitly force t to be an rvalue
}

Victor Bazarov

unread,
May 8, 2015, 1:55:41 PM5/8/15
to
You can't force anything into something it already is. A value returned
from a function is already a prvalue unless it's a reference. There is
no need to use 'std::move' on something that is about to be destroyed
due to going out of scope anyway.

Chris Vine

unread,
May 8, 2015, 6:19:54 PM5/8/15
to
The first approach is the correct one. Any recent compiler will use
return value optimization (which is permitted by the standard), and
construct the return value in the caller's stack frame. Although move
semantics are permitted as an optimization, it will not in fact be
used: RVO will be used instead.

Chris
0 new messages