如何有效地用枚举填充 2D std::数组

How to efficiently fill a 2D std::array with enum

本文关键字:2D std 填充 数组 枚举 有效地      更新时间:2023-10-16

我正在尝试找到一种有效且适当的方法来用enum值填充 2D std::array矩阵。 我正在这样做:

#include <iostream>
#include <array>
template<class T, size_t ROW, size_t COL>
using Matrix = std::array<std::array<T, COL>, ROW>;
enum class State { FREE = 0, BUSY, BLOCKED, RESERVED };
int main() {
  const int mapX = 4;
  const int mapY = 9;
  // create a 5x10 2D array
  Matrix<State, mapY, mapX> MapMatrix;
  // fill array with State::RESERVED value
  for (int y = 0; y <= mapY; y++) MapMatrix[y].fill(State::RESERVED);
  std::cout << "MapMatrix contains:n";
  for (int y = 0; y <= mapY; ++y) {
    for (int x = 0; x <= mapX; ++x) {
      std::cout << static_cast<int>(MapMatrix[x][y]) << " ";
    }
    std::cout << std::endl;
  }
  return 0;
}

我正在做的 for 循环是用enum值填充矩阵的最佳方式吗? 有没有办法在声明Matrix<State, mapY, mapX> MapMatrix期间填充矩阵(如构造函数(?

谢谢!

除非

用零填充它,或者显式指定每个元素,否则无法在初始化时填充它。如果您重新排列枚举以使RESERVED为零,则可以像这样初始化它:

Matrix<State, mapY, mapX> MapMatrix = {};

如果你做不到这一点,那么是的,for 循环可能是最好的选择。保持简单。但是你有一些问题。首先,您的评论说您正在创建一个 5x10 阵列,但事实并非如此。您正在创建一个 4x9 阵列。如果要创建 5x10 数组,则需要传递 5 和 10 作为模板参数。我想你可能会对大小为 N 的数组的最后一个元素是 N - 1 这一事实感到困惑。这个逐一的问题只与访问数组的元素有关,与指定数组的大小无关。

其次,你正在迭代数组的末尾,因为你的循环条件是 y <= mapY ,而不是y < mapY。但是,如果您只使用范围循环会更好。

for (auto& arr : MapMatrix)
    arr.fill(State::RESERVED);

我认为基于循环的初始化是一个很好的解决方案。

但是,只是为了好玩,我向您建议另一种基于std::index_sequence和模板包扩展的解决方案。

一个工作示例(索引已更正(

#include <iostream>
#include <utility>
#include <array>
template <typename T, std::size_t ROW, std::size_t COL>
using Matrix = std::array<std::array<T, COL>, ROW>;
enum class State { FREE = 0, BUSY, BLOCKED, RESERVED };
template <typename T, std::size_t ... Rs, std::size_t ... Cl>
Matrix<T, sizeof...(Rs), sizeof...(Cl)> initMat
   (T                          const & tVal,
    std::index_sequence<Rs...> const &,
    std::index_sequence<Cl...> const &)
 {
   auto col = std::array<T, sizeof...(Cl)>{ { ((void)Cl, tVal)... } };
   return Matrix<T, sizeof...(Rs), sizeof...(Cl)>
    { { ((void)Rs, col)... } };
 }
int main()
 {
   constexpr std::size_t mapX =  5U;
   constexpr std::size_t mapY = 10U;
   // create a 5x10 2D array
   auto MapMatrix = initMat(State::RESERVED,
                            std::make_index_sequence<mapX>(),
                            std::make_index_sequence<mapY>());
   std::cout << "MapMatrix contains:n";
   for ( auto y = 0U ; y < mapY ; ++y )
    {
      for ( auto x = 0U ; x < mapX ; ++x )
         std::cout << static_cast<int>(MapMatrix[x][y]) << " ";
      std::cout << std::endl;
    }
   return 0;
 }