使用预处理器生成默认值
Posted
技术标签:
【中文标题】使用预处理器生成默认值【英文标题】:Use Preprocessor to Generate Default Values 【发布时间】:2019-07-05 03:24:15 【问题描述】:我正在初始化一个包含数千个设置值的非常大的数组。我希望在编译时而不是运行时设置这些值,因为它们是固定的并且不会改变。
有没有办法自动生成这些值,也许使用预处理器?目前我正在使用另一个小程序生成这些值,然后分别简单地复制和粘贴这些值。
这是我正在生成的:
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++ 中,最好使用 constexpr 初始化程序来执行此操作。显然,复杂度取决于计算的复杂度。 OTOH,如果可行,我认为您当前的策略没有任何问题,但我不明白为什么您不直接写入将#include 的文件。这样,您可以将文件生成自动化作为构建过程的一部分,并避免干预复制和粘贴。 如果性能是一个问题,如果您从my_vector_default_values.h
中删除所有换行符,您可能会获得非常小的加速。
“有没有办法自动生成这些值”如果你告诉我们你用哪种方式生成它们,我们可能会说些什么。否则它需要心灵感应机器,但今天无法使用。
编辑令人困惑,原始示例询问int
,但编辑中有某种类调用(这对解决方案有很大影响)
好的,如果 OP 能够澄清这一点会很好(术语“默认值”通常意味着可以在运行时设置其他值,而选择 vector
表明他们想要运行时调整大小)
【参考方案1】:
这里是一些示例 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;
从the assembly output 可以看出,该表是在编译时计算的。
由于 C++17 std::array
允许 operator[]
以 constexpr 方式使用。在 C++17 之前,或者如果你想保留类的非默认可构造性,你必须使用可变参数模板来为数组生成一个花括号初始化器; this answer 提供了一个代码大纲,您可以修改它以使用您的生成算法。
【讨论】:
以上是关于使用预处理器生成默认值的主要内容,如果未能解决你的问题,请参考以下文章
用CMake设置Visual Studio工程中预处理器定义值
Kaggle泰坦尼克号数据机器学习实战:从缺失值处理数据探索性分析组合特征生成到多模型构建