gpt4 book ai didi

c++ - 将可变参数模板内容转储到二维数组

转载 作者:行者123 更新时间:2023-11-28 07:23:07 28 4
gpt4 key购买 nike

简要说明:

考虑一个用于保存整数值的基于可变参数模板的类型列表:

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... };
};

现在考虑我想对二维数组做同样的事情(换句话说,输入是类型列表的类型列表)。我们可以使用后面的元函数转储子数组,并使用第二个元函数转储外部数组:

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... };
};

我的问题(即深度上下文):

我正在编写编译时 Mandelbrot 分形渲染。渲染工作“正常”1,并将结果作为 RGB 值的方形二维类型列表(相同长度的类型列表的类型列表)返回。to_2d_array需要元函数将结果转储到数组并在运行时将其写入 PPM 文件。

The RGB values是等同于 std::integral_constant<unsigned int> 的完整包装器的实例, 它有一个成员 value它持有值(value)。

我上面贴的代码就是我写的in my implementation ,使用标准类型 ( std::integral_constant ) 而不是我自己的类型。上面的代码完美运行 at coliru ,但我的编译器 (GCC4.8.1) 说:

The initializer needs to be enclosed with an additional encloser-brace.

to_2d_array .如果我放置额外的大括号,赋值编译将失败,并显示“从指针到数组的无效转换”。

我做错了什么?是否有另一种近似方法可以实现这一点?

[1] 现在真的不行了,因为这个模板元编程怪兽的编译会导致 GCC 内部段错误 :)。但是这个问题与问题无关...

最佳答案

根据你的coliru example里面写的, 有几个问题我想指出。

  1. 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};
    }

    result 的类型在to_array<>to_2d_array<>等同于第一个例子。

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

在 Coliru 上使用 gcc 4.8.2、clang 3.3 和任何 gcc 4.8 进行测试。

关于c++ - 将可变参数模板内容转储到二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19148522/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com