Reputation: 23
The following code won't build, any feedback on the cause would be appreciated.
void bar(std::string str, int& a, int& b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
void run()
{
int a = 3;
int b = 5;
foo<std::string, int&, int&>(bar, a, b);
}
It is a modified implementation of the first solution proposed in this SO answer.
The IDE gives the following error on the line calling foo
:
C++ template<class T, class... Args> void foo(std::function<void (T, Args...)> fcn, Args ...args)
no instance of function template "foo" matches the argument list
argument types are:
(void (std::string str, int &a, int &b), int, int)
Tested separately, it seems like passing a fcn
argument with template arguments are fine. The issue seems to be with passing a function argument where the function can accept variadic template arguments.
Upvotes: 1
Views: 109
Reputation: 23
Thanks all. Going off of the answer by serkan the following seems to work.
#include <iostream>
#include <functional>
void bar(std::string str, int& a, int& b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, std::reference_wrapper<int>, std::reference_wrapper<int>)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, std::ref(a), std::ref(b));
foo((std::function<void(std::string, std::reference_wrapper<int>, std::reference_wrapper<int>)>)bar, std::ref(a), std::ref(b));
return 0;
}
I'll run more tests, there might still be some changes needed.
Upvotes: 1
Reputation: 146
#include <iostream>
#include <functional>
void bar(std::string str, int a, int b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, int, int)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, a, b);
return 0;
}
#include <iostream>
#include <functional>
void bar(std::string str, int* a, int* b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, int*, int*)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, &a, &b);
return 0;
}
Upvotes: 1
Reputation: 218323
Function (pointer) is not a std::function
, so doesn't work for deduction.
You might make Ts...
non deducible in that context
template<typename T, typename ... Args>
void foo(std::function<void(T, std::type_identity_t<Args>...)> fcn, Args ... args)
{
// Some code that calls fcn
}
or drop std::function
completely
template<typename T, typename F, typename ... Args>
requires (std::is_invocable<F, T, Args...>::value)
void foo(F fcn, Args&& ... args)
{
// Some code that calls fcn
}
Upvotes: 3