如何有效地用枚举填充 2D std::array
How to efficiently fill a 2D std::array with enum
我正在尝试找到一种有效且正确的方法来使用 enum
值填充二维 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
。但是,如果你只是使用一个 range-for 循环会更好。
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;
}
我正在尝试找到一种有效且正确的方法来使用 enum
值填充二维 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
。但是,如果你只是使用一个 range-for 循环会更好。
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;
}