Home > Mobile >  std::invoke does not like variadic template member functions?
std::invoke does not like variadic template member functions?

Time:09-25

I'm trying to call a variadic function template using std::invoke() and std::apply(). And I apologize ahead of time, because I'm basically dropping a snippet of code here and asking someone to help me understand the error messages to solve the problem.

So, in the example code below,

  • std::invoke() on the non-variadic template functions works fine
  • std::invoke() on the variadic template function does not compile
#include <functional>
#include <tuple>

struct Thing
{
    // Some simple functions to test things out
    int func0() { return 0; }
    int func1(int) { return 1; }
    int func2(int, int) { return 2; }

    // A variadic template function that causes problems below
    template<typename ...Args>
    int funcn(Args&&...) { return 99; }
};

int main()
{
    Thing thing;

    // These work fine
    std::invoke(&Thing::func0, thing);
    std::invoke(&Thing::func1, thing, 1);
    std::invoke(&Thing::func2, thing, 1, 2);

    // This one doesn't work
    std::invoke(
        &Thing::funcn, 
        thing, 
        1, 2, 3, 4
    );
}

The errors I'm getting are here:


Output of x86-64 clang 12.0.1 (Compiler #1)

 Wrap lines
<source>:26:5: error: no matching function for call to 'invoke'
    std::invoke(
    ^~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/lib/gcc/x86_64-linux-gnu/11.1.0/../../../../include/c  /11.1.0/functional:94:5: note: candidate template ignored: couldn't infer template argument '_Callable'
    invoke(_Callable&& __fn, _Args&&... __args)
    ^

CodePudding user response:

The std::invoke expect a callable function. The funcn is a function template, and you need to instantiate to get a real function out of it and there-by you can take the address of it.

That means (explicitly) provide the template parameter to the function, how you want to instantiate it, so that std::invoke can see the function which it can invoke.

std::invoke(
    &Thing::funcn<int, int, int, int>, // works now
    thing,
    1, 2, 3, 4
);
  • Related