用于使用开关展开循环的 C++ 模板?

标签 c++ templates c++11 switch-statement template-meta-programming

我的问题类似于Can one unroll a loop when working with an integer template parameter?但我想混合编译时间和运行时间。具体来说,我在编译时知道一个常量 NBLOCK 并且我想在变量 start_block 上写一个开关,它只在运行时才知道 NBLOCK是开关中的条目数。这是我使用宏得到的结果:

#define CASE_UNROLL(i_loop)         \
  case i_loop : \
    dst.blocks[i_loop+1] -= (load_unaligned_epi8(srcblock) != zero) & block1; \
    srcblock += sizeof(*srcblock);

  switch(start_block)
    {
      CASE_UNROLL(0);
#if NBLOCKS > 2
      CASE_UNROLL(1);
#endif
#if NBLOCKS > 3
      CASE_UNROLL(2);
#endif
#if NBLOCKS > 4
      CASE_UNROLL(3);
#endif
...
...
#if NBLOCKS > 15
      CASE_UNROLL(14);
#endif
#if NBLOCKS > 16
#error "Too many blocks"
#endif
    }

我觉得很丑。特别是如果我想将界限从 16 提高到 32。

我想知道是否可以使用一些模板元编程来编写它。困难的部分是,出于性能原因,使用跳转表而不是嵌套条件序列编译开关是至关重要的。

请注意,该问题与 C++/C++11 - Switch statement for variadic templates? 非常相似但据我所知,这里提出的解决方案是通过使用混合编译/调谐时间初始化函数指针数组来删除开关。我不能付钱给王子在这里调用一个函数。

如果需要一些讨厌的扩展,我会使用 GCC。

最佳答案

您可以简单地将 Boost.Preprocessor 与 BOOST_PP_REPEAT(COUNT, MACRO, DATA) 一起使用:

#define APPLY_FUNC(INDEX, FUNC) FUNC(INDEX);

// ...

switch(start_block)
{
    BOOST_PP_REPEAT(NBLOCK, APPLY_FUNC, CASE_UNROLL);
}

应该扩展为:

switch(start_block)
{
    CASE_UNROLL(0);
    CASE_UNROLL(1);
    CASE_UNROLL(2);
    // ...
    CASE_UNROLL(NBLOCK-1);
}

关于用于使用开关展开循环的 C++ 模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16982283/

相关文章:

c++ - 常量元组 - 但能够更改内容(引用)?

c++ - 删除的默认构造函数仍然是微不足道的吗?

c++ - 模板和参数相关查找

c++ - 如何使用此 protected 成员函数获取所需的输出

c++ - 检查方法是否为常量

templates - 模板中引用的字符串

c++ - Wt 编译问题

c++ - 用于在字符串中查找字符序列的预构建函数?

python - Django 模板 : How to display block of HTML based on a boolean field in model

c++ - 将整数或类型作为模板参数传递?