将可变参数模板内容转储到 2D 数组
Dump variadic template content to a 2D array
简要说明:
考虑一个基于可变模板的类型列表,用于保存整数值:
template<typename... Ts>
struct list {};
using my_int_list = list<std::integral_constant<0>,
std::integral_constant<1>,
std::integral_constant<2>>;
可以使用数组初始值设定项和可变参数包扩展将其转储到数组:
template<typename LIST>
struct to_array;
template<typename... Ts>
struct to_array<list<Ts...>>
{
static constexpr unsigned int result[] = { Ts::value... };
};
现在考虑我想对 2d 数组做同样的事情(换句话说,输入是字体列表的排字表(。我们可以使用后面的元函数来转储子数组,并使用第二个元函数来转储外部数组:
template<typename LIST>
struct to_2d_array;
template<typename... Ts>
struct to_2d_array<list<Ts...>>
{
using value_type = unsigned int; //To simplify things, suppose we know the type
//of the elements. Also suppose the array is
//squared.
static constexpr value_type result[sizeof...(Ts)][sizeof...(Ts)] = { to_array<Ts>::result... };
};
我的问题(即深入的背景(:
我正在编写一个编译时的曼德布洛特分形渲染。渲染工作"正常">1,它将结果作为 RGB 值的正方形 2d 字体列表(相同长度的字体列表的字体列表(返回。需要to_2d_array
元函数将结果转储到数组并在运行时将其写入 PPM 文件中。
RGB值是等价于std::integral_constant<unsigned int>
的整数包装器的实例,它有一个成员value
来保存该值。
我上面发布的代码正是我在实现中编写的代码,使用标准类型(std::integral_constant
(而不是我自己的类型。上面的代码在coliru上完美运行,但是我的编译器(GCC4.8.1(说:
初始值设定项需要用额外的封闭式大括号括起来。
在to_2d_array
.如果我加上额外的大括号,则 assigment 编译失败,并显示"从指针到数组的无效转换"。
我做错了什么?有没有另一种近似值来实现这一点?
[1] 它现在真的不起作用了,因为这个模板元编程怪物的编译会导致 GCC 内部分段错误:)。但是这个问题与问题无关...
根据你的 coliru 示例中所写的内容,我想指出几个问题。
-
result
的类型 .以下代码无法编译。
int main() { int x[] = {1, 2, 3}; int y[3][3] = {x, x, x}; }
而以下确实如此。
#include <array> int main() { std::array<int, 3> x = {1, 2, 3}; std::array<std::array<int, 3>, 3> y = {x, x, x}; }
to_array<>
和to_2d_array<>
中的result
类型等效于第一个示例。 -
result
被声明为static constexpr
,但缺少外联定义。
以下是为解决上述问题而进行修改的代码。
#include <array>
#include <iostream>
#include <type_traits>
template <typename... Ts>
struct list {};
template <typename List>
struct to_array;
template <typename... Ts>
struct to_array<list<Ts...>> {
using result_type = std::array<unsigned int, sizeof...(Ts)>;
/* Use std::array<> instead of C-array. */
static constexpr result_type result = { Ts::value... };
}; // ToArray<List<Ts...>>
/* Out-of-line definition for static constexpr variable. */
template <typename... Ts>
constexpr typename to_array<list<Ts...>>::result_type
to_array<list<Ts...>>::result;
template <typename List>
struct to_2d_array;
template <typename... Ts>
struct to_2d_array<list<Ts...>> {
using result_type =
std::array<std::array<unsigned int, sizeof...(Ts)>, sizeof...(Ts)>;
/* Use std::array<> instead of C-array. */
static constexpr result_type result = { to_array<Ts>::result... };
};
/* Out-of-line definition for static constexpr variable. */
template <typename... Ts>
constexpr typename to_2d_array<list<Ts...>>::result_type
to_2d_array<list<Ts...>>::result;
int main() {
using my_int_list = list<std::integral_constant<int, 0>,
std::integral_constant<int, 1>,
std::integral_constant<int, 2>>;
for (int i = 0; i < 3; ++i) {
std::cout << to_array<my_int_list>::result[i] << ' ';
} // for
std::cout << std::endl << std::endl;
using my_2d_list = list<my_int_list,my_int_list,my_int_list>;
/* Actually try printing the result. */
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
std::cout << to_2d_array<my_2d_list>::result[i][j] << ' ';
} // for
std::cout << std::endl;
} // for
}
指纹:
0 1 2
0 1 2
0 1 2
0 1 2
使用 gcc 4.8.2、clang 3.3 和 Coliru 上的任何 gcc 4.8 进行测试。
- 分段故障(堆芯转储)矢量
- Cppcheck生成xml转储文件
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 浮点异常(核心转储)#694457
- 分段错误(核心转储)但无法弄清楚
- 链接到libkcapi时没有核心转储
- 检测到堆栈粉碎:已终止 中止(核心已转储)
- 正在处理故障(堆芯转储)
- 分段错误(核心转储) - 使用 SavedModel 的 Tensorflow C++ API 进行推断
- 我不知道为什么这段代码会让核心被转储?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- C++指针无法在函数外部传递值和分段错误(核心转储)错误
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- 将可变参数模板内容转储到 2D 数组
- 将2D数组错误定位为参数会导致内存转储
- 在使用 memcpy 填充动态 2d 数组后删除动态 2D 数组时中止(核心转储)