Search

Using std::move to move elements in vectors

Concept widely used in game development.


Using std::move to move elements in vectors

std::move

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).

Usage examples

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 ?!


cpp cppdaily


Share



Comments