【发布时间】:2019-10-16 10:00:23
【问题描述】:
考虑:
static constexpr unsigned num_points{ 7810 };
std::array< double, num_points > axis;
for (int i = 0; i < num_points; ++i)
{
axis[i] = 180 + 0.1 * i;
}
axis 是一个类范围的常量。我想避免像任何其他全局变量一样初始化它。可以在编译时完成吗?
这是最后一个类:
// https://www.nist.gov/pml/atomic-spectroscopy-compendium-basic-ideas-notation-data-and-formulas/atomic-spectroscopy
// https://www.nist.gov/pml/atomic-spectra-database
struct Spectrum
{
static constexpr unsigned _num_points{ 7810 };
using Axis = std::array< double, _num_points >;
static constexpr Axis _x{ [] () // wavelength, nm
{
Axis a {};
for( unsigned i = 0; i < _num_points; ++i )
{
a[ i ] = 180 + 0.1 * i;
}
return a;
} () };
Axis _y {}; // radiance, W·sr−1·m−2
};
代码和变量的混合是难看的,但至少公式就在读者的眼前。任何其他解决方案都需要大量输入才能获得类内定义的常量和类型。
或者如果我改变我的壁炉,我可以简单地在运行时返回 lambda。
【问题讨论】:
-
如果您的数据在这种模式下确实是只读的,那么对于大多数硬件上的大多数用例,您最好在运行时计算它。 7810 * 8 字节对于阵列来说是一个很大的缓存占用空间。加载一个基数 + 比例因子只有 2 个双精度数 = 16 个字节。运行时计算很便宜:一次 int->FP 转换,一次 FMA 或一次 mul + add。 (加上加载常量)。所以是的,在缓存命中时,LUT 更快,但尤其是在循环内重复使用时,计算通常会很好。
标签: c++ initialization c++17 compile-time stdarray