c++parameter-pack

Use parameter pack to initialize map of templated


For a class that looks like this:

class A
{
public:
    template <int X> void foo(double param);

    const std::map<int, std::function<void(double)>> foo_map;
};

Where foo_map needs to be initialized in the ctor initializer list as

A::A() :
 foo_map{
          {2, [this](double p) { foo<2>(p); } }, 
          {6, [this](double p) { foo<6>(p); } },
          etc.
        }
{}

I.e. I need to fill the map with that pattern for a bunch of different ints.

Can I make a varadic template helper function with a parameter pack that will create that map with just the list of ints (and the class object pointer)?

A::A() :
  foo_map{make_foo_map(this, 2, 6, etc.)}
{}

I've tried

template <typename... Args>
std::map<int, std::function<void(double)>> make_foo_map(A* obj, Args&&... args)
{
  return std::map<int, std::function<void(double)>>{
    {args, [obj,args](double p) { obj->foo<args>(p); }}...
  };
}

But get a compiler error about there being no matching function call to A::foo<args>(p)


Solution

  • NTTP (non type template parameter) should be compile time, so cannot be regular argument, instead you might do:

    template <int... Ns>
    static std::map<int, std::function<void(double)>> make_foo_map(A* self)
    {
        return {{Ns, [self](double d){ self->foo<Ns>(d); }}...};
    }
    
    A() : foo_map{make_foo_map<2, 6 /*, etc */>(this)} {}
    

    Demo