How to Std::Move Objects Out of Functions? (C++11)

Is it possible to std::move objects out of functions? (C++11)

Given this example,

X foo ()
{
X x;
return x;
}

the following behavior is guaranteed:

• If X has an accessible copy or move constructor, the compiler may
choose to elide the copy. This is the so-called (named) return value
optimization ((N)RVO), which was specified even before C++11 and is
supported by most compilers.

• Otherwise, if X has a move constructor, x is moved.

• Otherwise, if X has a copy constructor, x is copied.

• Otherwise, a compile-time error is emitted.

Note also that returning an rvalue reference is an error if the returned object is a local nonstatic object:

X&& foo ()
{
X x;
return x; // ERROR: returns reference to nonexistent object
}

An rvalue reference is a reference, and returning it while referring to a local object means that you
return a reference to an object that doesn’t exist any more. Whether std::move() is used doesn’t
matter.

std::move() doesn't really move object; it only turns lvalues into rvalues.

Is it allowed to self-move an object in C++?

From cpp ref:

Also, the standard library functions called with xvalue arguments may assume the argument is the only reference to the object; if it was constructed from an lvalue with std::move, no aliasing checks are made. However, self-move-assignment of standard library types is guaranteed to place the object in a valid (but usually unspecified) state:

std::vector<int> v = {2, 3, 3};
v = std::move(v); // the value of v is unspecified

What can I do with a moved-from object?

Moved-from objects exist in an unspecified, but valid, state. That suggests that whilst the object might not be capable of doing much anymore, all of its member functions should still exhibit defined behaviour — including operator= — and all its members in a defined state- and it still requires destruction. The Standard gives no specific definitions because it would be unique to each UDT, but you might be able to find specifications for Standard types. Some like containers are relatively obvious — they just move their contents around and an empty container is a well-defined valid state. Primitives don't modify the moved-from object.

Side note: I believe it's T c = std::move(a) so that if the move constructor (or copy constructor if no move is provided) is explicit the function will fail.

What is std::move(), and when should it be used?

Wikipedia Page on C++11 R-value references and move constructors

  1. In C++11, in addition to copy constructors, objects can have move constructors.

    (And in addition to copy assignment operators, they have move assignment operators.)
  2. The move constructor is used instead of the copy constructor, if the object has type "rvalue-reference" (Type &&).
  3. std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it.

It's a new C++ way to avoid copies. For example, using a move constructor, a std::vector could just copy its internal pointer to data to the new object, leaving the moved object in an moved from state, therefore not copying all the data. This would be C++-valid.

Try googling for move semantics, rvalue, perfect forwarding.



Related Topics



Leave a reply



Submit