Search code examples
c++c++11templatesfunction-pointersfunction-call

Parameters pack not expanded with '...' even though ... is used


I am currently trying to create an event template class for my engine.

My event class has an std::vector<T> where T is going to be defined as a pointer to function where the event is needed.

When calling the event it will call every function that was added to the vector with the necessary arguments.

Problem is when trying to compiling this part of the code for calling the event.

At the moment it is written like this.

template <typename... Args>
void Call(Args ... args)
{
   for (T f : functions)
   {
      f->*(args...);
   }
}

Note that I have tried :

f->*((args), ...);
f->*(std::forward(args)...);
f->*(args)...;

and many other similar solutions.

Every time I tried to compile the code I ran into:

include/event.h:71:22: error: expected ‘)’ before ‘...’ token
             f->*(args...);
                      ^
include/event.h:71:26: error: parameter packs not expanded with ‘...’:
             f->*(args...);

I really don't understand the problem here.


Solution

  • The syntax of calling a function pointer and member function pointer with arguments are different.

    In case of a function pointer(i.e. free functions), you might do

    f(std::forward<Args>(args)...);
    

    In the case of a member function pointer, you need an object(or pointer to an object) to invoke the member function, with its arguments.

    (pointer_to_object->*f)(std::forward<Args>(args)...);
    

    However, if you have access to , just use std::invoke, which has suitable overloads for handling the cases mentioned above.

    #include <utility>    // std::forward
    #include <functional> // std::invoke
    
    template <typename... Args>
    void Call(Args&& ... args)
    //        ^^^^^^^^^^^^^^ --> also forwarding reference here
    {
       for (T f : functions)
       {
          std::invoke(f, std::forward<Args>(args)...);  // like this
       }
    }