Search code examples
c++templatesc++17variadic-templates

Convert variadic template ints to switch statement


I would like to do the following:

// 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);

such that it becomes

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;
  }
}

How can I generate a switch statement that enumerates all variadic template arguments as an efficient switch statement without manually writing the switch statement?


Solution

  • Compilers can turn chained-ifs into switch statements in assembly.

    A binary fold like this:

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

    does what you ask, down to the assembly:

    Live example - change the #if clause between 0 and 1 to swap between hand-crafted and generated switch statements.