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