5

I am trying to instantiate a function table (to emulate switch)

  template<size_t ... N>
  int f(std::index_sequence<N...>, int k)
  {
    static auto f_table = { []() { return N; }... };
    auto f = f_table.begin() + k;
    assert((*f)() == k);
    return (*f)();
  }

which fails with error: parameter packs not expanded with ‘...’:

I can get by with an extra wrapper function but why does lambda fail and is there a workaround?

Anycorn
  • 50,217
  • 42
  • 167
  • 261

1 Answers1

1

It was a bug that GCC doesn't expand template parameter pack that appears in a lambda-expression, which was fixed in GCC 8 eventually.

The other issue with the code as also mentioned in the comments is that every lambda in the list { []() { return N; }... } has its own distinct type, so one has to convert them into function pointers with + operator first:

#include <utility>
#include <cassert>

template<std::size_t ... N>
int f(std::index_sequence<N...>, std::size_t k) {
   static auto f_table = { +[]() { return N; }... };
   auto f = f_table.begin() + k;
   assert((*f)() == k);
   return (*f)();
}

int main() {
    f(std::make_index_sequence<3>{}, 2);
}

Demo: https://gcc.godbolt.org/z/jWrfn7d6W

Fedor
  • 17,146
  • 13
  • 40
  • 131