c++ 将变量模板int转换为switch语句

a14dhokn  于 2023-01-22  发布在  其他
关注(0)|答案(3)|浏览(136)

我想做以下几点:

// function that depends on key to do stuff
template <int key>
void bar()  {...}

template <int ...Keys>
void foo(int key) {
   // WHAT SHOULD BE HERE?
}

std::cin >> key;
foo<1,3,5,7,9>(key);

使得它变成

template <int ...Key>
void foo(int key) {
  switch (key) {
      case 1: bar<1>();break;
      case 3: bar<3>();break;
      case 5: bar<5>();break;
      case 7: bar<7>();break;
      case 9: bar<9>();break;
      default: break;
  }
}

如何生成一个switch语句,它枚举所有可变参数模板参数,作为一个高效的switch语句,而不需要手动编写switch语句?

kcugc4gi

kcugc4gi1#

编译器可以将链式if转换为汇编中的switch语句。
像这样的双重褶皱:

( [&key]{
    if(key==Keys) {
      bar<Keys>();
      return true;
    }
    return false; 
  }()||... );

按照你的要求去做,一直到议会:
Live example-在0和1之间更改#if子句,以便在手工创建的switch语句和生成的switch语句之间进行交换。

bn31dyow

bn31dyow2#

您可以使用带有空/额外foo的参数包扩展来关闭包,如下例所示。

#include <cstdio>

template <int key>
void bar()  {
    printf( "%d ", key );
}

template < typename = void  >
void foo(int key ) {
}

template <int val, int... Keys  >
void foo(int key ) {
    if ( val == key ) bar<val>();
    else { 
        foo<Keys...>(key);
    }
}

int main() {
    for ( int key = 0; key<10; ++key ) {
        foo<1,3,5,7,9>(key);
    }
}

它打印

Program returned: 0
Program stdout
1 3 5 7 9

神箭:https://godbolt.org/z/zE1cE9eob

s3fp2yjn

s3fp2yjn3#

根据Yakk的回答,我提出了下面的解决方案,使用三元和逗号操作符,避免使用lambda

template <int ...Keys>
void foo (int key) {
  (void)((Keys == key ? (void)bar<Keys>(), 0 : 0), ...);
}

或者,也许更好

template <int ...Keys>
void foo (int key) {
  (void)((Keys == key ? (void)bar<Keys>(), true : false) || ...);
}

相关问题