使用函数调用初始化静态全局数据(在编译时)

Initializing static global data using function call (at compile time)

本文关键字:编译 数据 全局 函数调用 初始化 静态      更新时间:2023-10-16

我试图通过在编译时计算数字序列并将其存储为静态向量来节省计算时间(但目前我可能会在运行时开始计算一次)。我试图做的一个简单的(不是编译的)例子是:

#include <vector>
using namespace std;
static vector<vector<int> > STATIC_THING(4, vector<int>(4));
void Generator(int x, int y, vector<int> *output) {
  // Heavy computing goes here
  for(int i=0; i < 4; ++i)
    (*output)[i] = x * y;
  return;
}   
static void FillThings() {
  for(int x=0; x < 4; ++x)
    for(int y=0; y < 4; ++y)
      Generator(x, y, &STATIC_THING[x]);
}   
FillThings();
int main() {
}   

除了预计算和将序列硬编码到数组之外,还有其他方法可以让编译器对此进行提升吗?我觉得应该有一种方法,至少在第一个#include的头上完成这项工作,但我只见过它在类中完成。如果可以在编译时方便计算,我可以使用数组而不是矢量。

编辑:

  • 尽管有人建议使用模板元编程,但我实际的生成器算法太复杂了,不适合使用这种技术。

  • 使用查找表似乎是我唯一一个可以避免运行时计算的选项;如果性能在未来仍然是一个问题,我会放弃这一点。

这样做:

static int FillThings() {
  for(int x=0; x < 4; ++x)
    for(int y=0; y < 4; ++y)
     Generator(x, y, &STATIC_THING[x]);
  return 9087;
}   
static int q = FillThings();

如果不能通过大括号初始化器从实际文本进行初始化,那么可以执行以下操作:

typename std::vector<std::vector<int>> my_vector;
static my_vector make_static_data()
{
    my_vector result;
    // ... populate ...
    return result;
}
static const my_vector static_data = make_static_data();

没那么容易:std::vector是一个动态结构。它不是"可填充的"或"编译时"。它可以在启动时通过初始化一个静态变量并返回一个调用的函数或lambda来填充,该函数实际上填充了向量。

这可能是一种方式。

但是,一个合适的"编译时向量"应该看起来像一个模板,其"索引"是作为参数给定的int,就像一样

template<unsigned idx>
struct THING
{
    static const int value = .... //put a costant expression here
};

以用作CCD_ 1。

"常量表达式"可以是function(THING<idx-1>::value),递归地向下到专门的

temnplate<>
struct THING<0U> {};

这将停止编译器递归。

然而,也有一些限制:定义value静态成员的表达式必须是constexpr(因此,只有整数类型、内置的oers,没有<cmath>,只有用constexpr声明的函数),用作idx的值本身必须是常量(而不是变量)。