如何在编译时初始化 constexpr 多维数组?

mar*_*964 6 c++ arrays initialization multidimensional-array constexpr

我正在尝试初始化一个多维数组,虽然可以在启动时填充该数组一次,但我真的更喜欢该数组constexpr,所以我想知道是否有一种方法可以让编译器为我执行此操作,特别是因为我可以提供一个 constexpr 函数,该函数接受每个索引的参数并返回数组应位于索引处的值。

例如:

constexpr bool test_values[64][64][64][64] = {
... // magic goes here
};
Run Code Online (Sandbox Code Playgroud)

我有一个函数constexpr bool f(int,int,int,int)可以告诉我每个元素应该是什么。我更喜欢通过数组访问条目,因为进行数组查找比调用 f() 获取非常量值更快。

我发现的大多数与在运行时初始化数组相关的其他问题都使用 std::array 而不是 C 数组,而且我找不到的问题都是多维的。我曾尝试将多维数组展开为一维数组,并使用 std::array 方法,例如我在这个问题的答案之一中找到的方法,但我发现 gcc 9.1 生成的结果代码仍然填充了数组在启动时一次,而不是编译器直接生成数组。

我可以做些什么来让编译器填充这种数组,还是我必须保留test_values有效的非constexpr,并在运行时初始化一次?

编辑:

澄清一下,我本质上并不反对使用 std::array 而不是内置的 C 风格数组,但我不认为 std::arrays 对多维特别友好,并且使用一维数组会混淆我的内容程序需要做的事情(坦率地说,如果必须的话,我愿意将其实现为一维 std::array ,但是多维数组感觉比手动展开的同等大小的一维数组更容易混淆,这就是为什么我用多维 C 数组来描述它)。

Jar*_*d42 3

C 数组不可复制,因此实际上不可能使用 function,但是使用std::array,您可以创建 constexpr 函数(尽管 C++11 受到更多限制)

constexpr auto generate()
{
    std::array<std::array<std::array<std::array<bool, 64>, 64>, 64>, 64> res{};

    for (int a = 0; a != 64; ++a) {
        for (int b = 0; b != 64; ++b) {
            for (int c = 0; c != 64; ++c) {
                for (int d = 0; d != 64; ++d) {
                     res[a][b][c][d] = f(a, b, c, d);
                }
            }
        }
    }

    return res;
}

constexpr auto test_values = generate();
Run Code Online (Sandbox Code Playgroud)

如果您确实需要 C 数组,则可以将其包装在结构中并使用类似的代码。