【问题标题】: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 表明他们想要运行时调整大小)

标签: c++ c-preprocessor


【解决方案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 提供了一个代码大纲,您可以修改它以使用您的生成算法。

【讨论】:

    猜你喜欢
    • 2021-06-02
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多