鉴于我想对一些数据执行过滤,我如何才能避免在运行时生成这些数据,同时保持改变这些过滤器的大小和数据分布的灵 active ,同时保持漂亮干净的可重用代码。我知道我可以使用模板来执行如下操作:
template <int x> class Filter
{
static const float f;
static const Filter<x-1> next;
inline float* begin(const Filter<x>& el){ return &f; }
inline float* end(const Filter<x>& el) { return (&f)+x+1; }
};
template <> class Filter<0>
{
static const float f;
inline float* begin(const Filter<0>& el){ return &f; }
inline float* end(const Filter<0>& el) { return (&f)+1; }
};
template <int x> const float Filter<x>::f = someDistribution(x);
template <> const float Filter<0>::f = someDistribution(0);
这确实会根据 someDistribution(...) 根据过滤器对象中的索引 x 在我的过滤器中生成数据。然而,我的使用有一些缺点......
1) 我认为我说得对,虽然此数据不是在对象构造时生成的,但它是在程序启动时生成的。 - 这是我可以容忍的,尽管宁愿在 comiletime 计算过滤器并在那时和那里烘烤(这甚至可能用于 float 据吗?)
2) 过滤器不会实例化“下一个”成员,除非有一个遍历结构长度的成员函数(在某处被调用!),即
// inside template<int x> class Filter
inline void instantiate() const { next.instantiate(); };
// then inside template<> class Filter<0>
inline void instantiate() const { };
我一定是在要求 plunging 实例化函数时做错了,这使易于维护的子句失败了。
编辑:我关心这里的原因是我想确保实例化 next
成员,这样我就可以使用开始和结束函数遍历静态“数组”。
那么首先我该如何解决问题 2 并取消实例化函数,其次是否有可能解决问题 1 以便在编译时动态生成此数据并返回。
(注意我在类似问题上使用了 python 预编译脚本来生成包含过滤器数据的源文件,但我不想在这里使用它,因为那是它自己的鱼缸!)
最佳答案
因为你不能使用contexpr
...关于你的问题:
除非您正在搜索下一个最大的质数,否则您不应该因为在启动时只进行一次简单计算而烦恼。尝试对其进行测量,您可能会发现初始化在不到一毫秒的时间内完成。
也就是说,在启动时计算的值表现为变量(每次使用时都必须
询问
它们的值),而编译时常量的值始终是已知的。因此前者可能会慢一点,但可能没有任何意义。在造成不便之前始终先进行测量。
再一次,你为什么关心?如果代码中的任何地方都没有使用特定
x
的Filter
类型,为什么该值应该在某处附近?如果模板静态相互依赖,它们就会有问题 - 在您的情况下,它们不会相互依赖,每个
f
都是自治的。
综上所述,一个很好的修补工具是 http://gcc.godbolt.org/ - 您会在键入时看到程序集。它不支持 MS 编译器,但它可以让您很好地猜测编译器如何优化内容。
如果你的分配足够简单,可以成为一个宏,它将是一个编译时常量:
#define someDistribution(x) x * x
template <int x> struct Filter
{
static const float f;
};
template <int x> const float Filter<x>::f = someDistribution(x);
int main()
{
return Filter<200>::f + Filter<100>::f;
}
程序集(Clang):
main: # @main
movl $50000, %eax # imm = 0xC350
ret
如果您将 someDistribution
更改为函数,即使是内联函数,您也会发现必须进行计算。
编辑:请记住,您可以使用宏做任何事情,包括为某些值“专门化”它们。简单的分发应该是预处理器友好的。
关于c++ - 如何在编译时静态生成 float 据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19729966/