假设我们想要在编译时构建一个非平凡的表格
template<int N, int M>
constexpr auto foo()
{
std::array<std::array<int, N>, M> a = {};
for(int m = 1; m < M; m++)
for(int n = 1; n < N; n++)
{
// For exposition only
auto x = (m ^ 42) + (n << 3) - m;
auto y = (n ^ 420) + (m % 420);
a[m][n] = (a[(x + m) % m][(y + n) % n] + (x ^ y)) % 0xFACADE;
}
return a;
}
constexpr auto bar(int n, int m)
{
constexpr auto dim = /* something */;
constexpr auto table = foo<dim, dim>();
return table[n][m];
}
只需要稍微一点点就能让编译时间超过极限。另一种方法是通过脚本生成表格作为源代码,显然这种方法要好得多。如何减少此类函数的编译时间?
一些动机
constexpr
函数与常规函数有很大的不同,明显表现在它们比普通函数执行得慢得多。除了由编译器执行外,它们还进行边界检查、溢出检查以及几乎所有防止UB的检查。我怀疑这使得从常规函数中获得的大部分直觉都变得无用了。