c++ - 如何在编译时静态生成 float 据?

标签 c++ visual-studio-2013 compile-time data-generation

鉴于我想对一些数据执行过滤,我如何才能避免在运行时生成这些数据,同时保持改变这些过滤器的大小和数据分布的灵 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...关于你的问题:

  1. 除非您正在搜索下一个最大的质数,否则您不应该因为在启动时只进行一次简单计算而烦恼。尝试对其进行测量,您可能会发现初始化在不到一毫秒的时间内完成。

    也就是说,在启动时计算的值表现为变量(每次使用时都必须询问它们的值),而编译时常量的值始终是已知的。因此前者可能会慢一点,但可能没有任何意义。

    在造成不便之前始终先进行测量。

  2. 再一次,你为什么关心?如果代码中的任何地方都没有使用特定 xFilter 类型,为什么该值应该在某处附近?

    如果模板静态相互依赖,它们就会有问题 - 在您的情况下,它们不会相互依赖,每个 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/

相关文章:

c++ - Visual Studio中相互依赖的项目的并行编译

c++ - 如何在编译时在初始化列表中包含不同数量的对象?

c++ - 如何将范围信息传递给 C++ 编译器?

c++ - IOKit 和获取唯一 ID

c++ - GNU/G++ 4.9(2.95.3 之前的版本)的 C++11 中的 string_char_traits<char>

c++ - OS X 上的 OpenGL 版本支持

c++ - std::array 编译时间扣除

c++ - 如何在 const wchar_t* 参数处进行串联?

c++ - 关联容器的迭代器不依赖于比较器模板参数

c# - 在哪里可以找到 Microsoft.VisualStudio.QualityTools.WebTestFramework