-
Notifications
You must be signed in to change notification settings - Fork 0
std::move in c 11
The concept is very simple, every expression that results in a reference for a memory location is an l-value expression. The “L” stands for left-side, meaning that it can be on the left side of an assign operator “=”. An example is a variable declaration.
In simpler terms, if we can take a reference to a memory location from the expression result, it is an l-value.
All l-values are r-values but not all r-values are l-values. If we think on the left-right side of the assign operator, an l-value can be on both left and right sides, but an r-value cannot be on the left side. An example of an r-value is a return of a function that is not a reference type.
size_t val = 0;
// val expression is l-value
val = 1;
size_t fn() { // ... }
// Result of fn call expr is an r-value
fn();
//It cannot be an l-value
fn() = val; // compilation error
size_t& fn_ref() { // ... }
//It is an l-value
fn_ref() = val; // allowed
std::vector<std::string> all_strings;
for(int i = 0; i < aLenght; ++i) {
std::string result = aCallThatProducesAStr(i);
// Note that push_back result will copy the contents of
// result to an new object that will be stored in the vector.
// all_strings.emplace_back(result);
// Since is the last use of result string object, move
// which is more efficient.
all_strings.emplace_back(std::move(result));
// Any use of result variable after the move is undefined behavior.
}
std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.