I have a function which executes another function in worker thread:
void run_in_worker_thread( std::function< void( ) > proc )
Now I would like to implement function schedule() which takes proc() function as argument and returns function which executes proc() in worker thread via run_in_worker_thread().
Here is my implementation:
#include <iostream>
#include <functional>
using namespace std;
class Test
{
public:
void run_in_worker_thread( std::function< void( ) > proc )
{
std::cout << "execute in worker thread\n";
proc();
}
template < class... TArgs >
std::function< void( TArgs... ) >
schedule( std::function< void( TArgs... ) > proc )
{
std::function< void( TArgs... ) > f
= [this, proc]( TArgs... args ) { run_in_worker_thread( [=]( ) { proc( args... ); } ); };
return f;
}
};
int main()
{
Test test;
std::function<void(int, int)> my_funciton =
[](int a, int b) {std::cout << "got " << a << " and " << b << "\n";};
auto f2 = test.schedule( my_funciton );
f2(1, 2);
return 0;
}
The problem is that my schedule() requires std::function as argument. For instance, the following call leads to a compilation error:
auto my_funciton = [](int a, int b) {std::cout << "got " << a << " and " << b << "\n";};
auto f2 = test.schedule( my_funciton );
The issue is that a std::function
is a polymorphic wrapper around a callable object. Lambdas are not std::function
s. Just like string literals are not std::string
s. In your first example, you do this:
std::function<void(int, int)> my_funciton =
[](int a, int b) {std::cout << "got " << a << " and " << b << "\n";};
You're constructing a std::function
from the lambda. The schedule
function is able to deduce the signature of the function without problems.
In your second example, you do this:
auto my_funciton = [](int a, int b) {std::cout << "got " << a << " and " << b << "\n";};
Then you get an error because std::function<void (Args...)>
can't be matched against the lambda. The solution to this is to allow schedule
to accept any callable object, not just std::function
.
template <typename Func>
auto schedule(Func proc) {
return [this, proc](auto... args) {
run_in_worker_thread([=]() {
proc(args...);
});
};
}