使用预处理程序生成默认值

rhu*_*hes 6 c++ c-preprocessor

我正在初始化一个包含数千个设置值的大型数组。我希望这些值在编译时设置,而不是在运行时设置,因为它们是固定的并且不会更改。

是否有可能使用预处理器自动生成这些值的方法?目前,我正在使用另一个小程序生成这些值,然后分别简单地复制和粘贴这些值。

这是我生成的:

class MyClass
{
public:
    MyClass(int x, int y, int z) : X(x), Y(y), Z(z) {}

    int X, Y, Z;
};

std::vector<MyClass> my_vector{
    #include "my_vector_default_values.h"
};
Run Code Online (Sandbox Code Playgroud)

my_vector_default_values.h

MyClass(0, 0, 1),
MyClass(0, 0, 2),
MyClass(0, 0, 3),
MyClass(0, 0, 4),
// etc... for thousands of lines
// ...
Run Code Online (Sandbox Code Playgroud)

编辑:

我生成的实际值生成如下(这是C#程序):

var sb = new StringBuilder();

var sizeX = 32;
var sizeY = 32;
var sizeZ = 32;

for (var x = 0; x < sizeX; x++)
{
    for (var y = 0; y < sizeY; y++)
    {
        for (var z = 0; z < sizeZ; z++)
        {
            sb.AppendLine($"MyClass({x}, {y}, {z}),");
        }
    }
}

var s = sb.ToString();
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 4

如果您可以使类成为默认可构造的,这里是一些示例 C++17 代码:

#include <array>

const size_t gX = 32, gY = 32, gZ = 32;

class MyClass
{
public:
    int X, Y, Z;
};

constexpr std::array<MyClass, gX*gY*gZ> gen()
{
    std::array<MyClass, gX*gY*gZ> r{};
    size_t n = 0;

    for (int x = 0; x < gX; ++x)
        for (int y = 0; y < gY; ++y)
            for (int z = 0; z < gZ; ++z)
                r[n++] = { x, y, z };

    return r;
}

extern constexpr auto global = gen();

int main()
{
    return global[35].Z;
}
Run Code Online (Sandbox Code Playgroud)

正如您从汇编输出中看到的,该表是在编译时计算的。


由于 C++17std::array允许[]以 constexpr 方式使用运算符。在 C++17 之前,或者如果您想保留类的非默认构造性,则必须使用可变参数模板为数组生成带花括号的初始值设定项;这个答案提供了一个代码大纲,您可以修改它以使用您的生成算法。