使用预处理器生成默认值
Use Preprocessor to Generate Default Values
我正在初始化一个包含数千个设置值的非常大的数组。我希望这些值在编译时设置而不是 运行 时间,因为它们是固定的并且不会改变。
有没有办法自动生成这些值,也许使用预处理器?目前我正在使用另一个小程序生成这些值,然后简单地分别复制和粘贴这些值。
这是我生成的内容:
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"
};
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
// ...
编辑:
我生成的实际值生成如下(这是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();
这里是一些示例 C++17 代码,如果你能使 class default-constructible:
#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;
}
正如您从 the assembly output 中看到的那样,table 是在 compile-time 处计算的。
因为 C++17 std::array
允许 operator[]
以 constexpr 方式使用。在 C++17 之前,或者如果你想保留 class 的 non-default-constructibility,你必须使用可变参数模板为数组生成花括号初始化程序; this answer 提供了一个代码大纲,您可以修改它以使用您的生成算法。
我正在初始化一个包含数千个设置值的非常大的数组。我希望这些值在编译时设置而不是 运行 时间,因为它们是固定的并且不会改变。
有没有办法自动生成这些值,也许使用预处理器?目前我正在使用另一个小程序生成这些值,然后简单地分别复制和粘贴这些值。
这是我生成的内容:
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"
};
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
// ...
编辑:
我生成的实际值生成如下(这是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();
这里是一些示例 C++17 代码,如果你能使 class default-constructible:
#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;
}
正如您从 the assembly output 中看到的那样,table 是在 compile-time 处计算的。
因为 C++17 std::array
允许 operator[]
以 constexpr 方式使用。在 C++17 之前,或者如果你想保留 class 的 non-default-constructibility,你必须使用可变参数模板为数组生成花括号初始化程序; this answer 提供了一个代码大纲,您可以修改它以使用您的生成算法。