用另一个 constexpr 数组对成员数组进行大括号初始化
Brace initialization of a member array with another constexpr array
让我们考虑以下说明性示例代码:
using matrix_t = double[2][2];
constexpr matrix_t zero_matrix = {
{0.0, 0.0},
{0.0, 0.0}
};
constexpr matrix_t identity_matrix = {
{1.0, 0.0},
{0.0, 1.0}
};
struct wrapped_matrix_t
{
matrix_t matrix;
};
constexpr wrapped_matrix_t zero_wrapped_matrix = {
//zero_matrix
{
{zero_matrix[0][0], zero_matrix[0][1]},
{zero_matrix[1][0], zero_matrix[1][1]}
}
};
constexpr wrapped_matrix_t identity_wrapped_matrix = {
//identity_matrix
{
{identity_matrix[0][0], identity_matrix[0][1]},
{identity_matrix[1][0], identity_matrix[1][1]}
}
};
现在我希望能够通过constexpr
数组zero_matrix
和identity_matrix
来初始化其他类型的matrix_t
成员。然而,这似乎是不可能的。或者至少简单地使用名称是行不通的。
我得出的最好的结果是重用值来引用索引。但这远非完美。
有没有办法在这样的初始化中直接使用 zero_matrix
和identity_matrix
?
(我正在用-Wall -Wextra -pedantic -std=c++11
检查GCC 6.3.0。
如果您不能使用 std::array
并且无法访问 wrapped_matrix_t
的实现,则可以在初始化包装器时使用元编程生成源数组的索引。最终代码将如下所示:
constexpr wrapped_matrix_t zero_wrapped_matrix = from_array(zero_matrix);
constexpr wrapped_matrix_t identity_wrapped_matrix = from_array(identity_matrix);
我假设matrix_t
是double[2 * 2]
,但下面的技术可以推广到N
维数组。
以下是实现详细信息:
template <typename Array, std::size_t... Is>
constexpr auto from_array_impl(const Array& arr, std::index_sequence<Is...>)
{
return wrapped_matrix_t{arr[Is]...};
}
template <std::size_t N>
constexpr auto from_array(const double(&arr)[N])
{
return from_array_impl(arr, std::make_index_sequence<N>());
}
我基本上是将数组的大小与引用相匹配,并从中构建一个0..N
索引序列。然后,我通过用序列索引数组来创建wrapped_matrix_t
。
魔杖盒上的现场示例
以下是 2D 数组的可能实现:
template <std::size_t W, typename Array, std::size_t... Is>
constexpr auto from_array_impl(const Array& arr, std::index_sequence<Is...>)
{
return wrapped_matrix_t{(arr[Is % W][Is / W])...};
}
template <std::size_t W, std::size_t H>
constexpr auto from_array(const double(&arr)[W][H])
{
return from_array_impl<W>(arr, std::make_index_sequence<W * H>());
}
魔杖盒上的现场示例
您可以使用
std::array
并将表示形式更改为一维数组。
using matrix_t = std::array<double, 2 * 2>;
constexpr matrix_t zero_matrix = {
{0.0, 0.0,
0.0, 0.0}
};
constexpr matrix_t identity_matrix = {
{1.0, 0.0,
0.0, 1.0}
};
struct wrapped_matrix_t
{
matrix_t matrix;
};
constexpr wrapped_matrix_t zero_wrapped_matrix{zero_matrix};
constexpr wrapped_matrix_t identity_wrapped_matrix{zero_matrix};
魔杖盒上的现场示例
为了像访问 2D 数组一样访问 1D 数组,您可以使用以下公式: (x, y) => x + y * width
.
如果您愿意,可以在std::array
周围创建一个包装器,以提供类似 2D 的界面。
相关文章:
- C++使用整数的压缩数组初始化对象
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 new 和 值进行数组初始化,但没有显式数量的元素
- 运行时C++数组初始化问题
- 使用带有参数包的数组的成员数组初始化类
- 仅通过C++中数组初始化的不同方法,即可在同一输入上获得两个不同的答案
- C++ 2 个指针数组初始化 C2440
- C++结构字符数组初始化
- C++中的多维数组初始化
- constexpr数组初始化
- C++引物动态数组初始化程序的数目超过大小
- 使用std::index_sequence对std::数组初始化进行包扩展
- 当 std 数组初始化太小时,C++会引发错误吗?
- 如何确定结构数组初始化的大小?
- Qt并发错误:数组初始化需要大括号括起来的初始值设定项列表
- 此代码中的数组初始化样式是什么?这是标准的吗?
- C++ 使用数组初始化时的 STL 向量内存管理