std::move
is used to indicate that an object can be “moved from..to”, that is, allowing the efficient transfer of resources from t to another object.
In particular, std::move
produces an xvalue
expression that identifies its argument t
. It is exactly equivalent to a static_cast
for a reference type rvalue
.
Its syntax is: std::move(first, last, result)
.
Let’s suppose we are creating a Tic Tac Toe game and we have a namespace
with the following struct
that stores the coordinates of our game:
namespace terroo {
struct Coordinates {
int x, y;
};
}
And we have the vectors (v1
, v2
and v3
) with the following coordinates:
std::vector<terroo::Coordinates> v1 = { {0,0}, {0,1}, {0,2} }, v2, v3;
for (size_t i = 0; i < v1.size(); ++i) {
v2.push_back({1, v1[i].y});
v3.push_back({2, v1[i].y});
}
for (size_t i = 0; i < v1.size(); ++i) {
std::cout << v1[i].x << ',' << v1[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v2.size(); ++i) {
std::cout << v2[i].x << ',' << v2[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v3.size(); ++i) {
std::cout << v3[i].x << ',' << v3[i].y << ' ';
}
std::cout << '\n';
Output will be:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
Now let’s assume that a player won by marking the diagonal from left to right.
Using std::move
for us to move 0.0 to 1.1 and to 2.2 we would use this code:
std::move(v1.begin(), v1.begin() + 1, v2.begin() + 1); // move 0,0 to 1,1
std::move(v1.begin(), v1.begin() + 1, v3.begin() + 2); // move 0,0 to 2,2
Running our code and displaying the output after the player wins would be:
0,0 0,1 0,2
1,0 1,1 1,2
2,0 2,1 2,2
-----------
0,0 0,1 0,2
1,0 0,0 1,2
2,0 2,1 0,0
Complete code created for this example:
#include <iostream>
#include <vector>
namespace terroo {
struct Coordinates {
int x, y;
};
}
int main(){
std::vector<terroo::Coordinates> v1 = { {0,0}, {0,1}, {0,2} }, v2, v3;
for (size_t i = 0; i < v1.size(); ++i) {
v2.push_back({1, v1[i].y});
v3.push_back({2, v1[i].y});
}
for (size_t i = 0; i < v1.size(); ++i) {
std::cout << v1[i].x << ',' << v1[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v2.size(); ++i) {
std::cout << v2[i].x << ',' << v2[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v3.size(); ++i) {
std::cout << v3[i].x << ',' << v3[i].y << ' ';
}
std::cout << '\n';
std::cout << "------" << '\n';
std::move(v1.begin(), v1.begin() + 1, v2.begin() + 1);
std::move(v1.begin(), v1.begin() + 1, v3.begin() + 2);
for (size_t i = 0; i < v1.size(); ++i) {
std::cout << v1[i].x << ',' << v1[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v2.size(); ++i) {
std::cout << v2[i].x << ',' << v2[i].y << ' ';
}
std::cout << '\n';
for (size_t i = 0; i < v3.size(); ++i) {
std::cout << v3[i].x << ',' << v3[i].y << ' ';
}
std::cout << '\n';
return 0;
}
Very simple, right ?!