Passing Class Method to std::async in C++ [duplicate] - c++

How can I operate std::async call on a member function?
Example:
class Person{
public:
void sum(int i){
cout << i << endl;
}
};
int main(int argc, char **argv) {
Person person;
async(&Person::sum,&person,4);
}
I want to call to sum async.
Person p;
call async to p.sum(xxx)
I didnt figure out if i can do it with std::async.
Dont want to use boost.
Looking for a one line async call way.

Something like this:
auto f = std::async(&Person::sum, &p, xxx);
or
auto f = std::async(std::launch::async, &Person::sum, &p, xxx);
where p is a Person instance and xxx is an int.
This simple demo works with GCC 4.6.3:
#include <future>
#include <iostream>
struct Foo
{
Foo() : data(0) {}
void sum(int i) { data +=i;}
int data;
};
int main()
{
Foo foo;
auto f = std::async(&Foo::sum, &foo, 42);
f.get();
std::cout << foo.data << "\n";
}

There are several ways, but I find it's most clear to use a lambda, like this:
int i=42;
Person p;
auto theasync=std::async([&p,i]{ return p.sum(i);});
This creates a std::future. For a complete example of this, I have a full example including a async-capable setup of mingw here:
http://scrupulousabstractions.tumblr.com/post/36441490955/eclipse-mingw-builds
You need to make sure that p is thread safe and that the &p reference is valid until the async is joined. (You can also hold p with a shared pointer, or in c++14, a unique_ptr or even move p into the lambda.)

Related

No matching overloaded function found - Threads

For the code snippet below, I keep getting the invoke error C6272. I have tried multiple things - passing using ref, without it and even testing as a simple thread. For context, the member function is a function that multiplies two sparse matrices and adds them to a linked list. Without using threads, the function works fine but threads returns an error.
mutex m;
vector<thread> a;
for (int q = 0; q < rhs.num_columns_; q++) {
a.push_back(thread(&SparseMatrix::mul_node, rhs_rows, lhs_rows, q, ref(newMatrix), ref(m)));
}
for (thread& t : a) {
t.join();
}
Declaration of the mul_node function
void SparseMatrix::mul_node(vector<vector<int>> rhs, vector<vector<int>> lhs, int pos_rhs, row_node* &newMatrix, mutex &m) const`
I have not been able to find a solution yet for the problem above, please let me know what exactly is causing the issue and how I can fix it? Thank you
Since the member function is not static you need to pass a pointer to the instance of the SparseMatrix on to the std::thread constructor too.
Simplified example:
#include <iostream>
#include <thread>
struct foo {
~foo() {
if(th.joinable()) th.join();
}
void run() {
th = std::thread(&foo::thread_func, this, 10, 20);
// ^^^^
}
void thread_func(int a, int b) {
std::cout << "doing the stuff " << a << ' ' << b << '\n';
}
std::thread th;
};
int main() {
foo f;
f.run();
}
Here 10 and 20 are passed as parameters to this->thread_func.

C++ future async not working inside class [duplicate]

How can I operate std::async call on a member function?
Example:
class Person{
public:
void sum(int i){
cout << i << endl;
}
};
int main(int argc, char **argv) {
Person person;
async(&Person::sum,&person,4);
}
I want to call to sum async.
Person p;
call async to p.sum(xxx)
I didnt figure out if i can do it with std::async.
Dont want to use boost.
Looking for a one line async call way.
Something like this:
auto f = std::async(&Person::sum, &p, xxx);
or
auto f = std::async(std::launch::async, &Person::sum, &p, xxx);
where p is a Person instance and xxx is an int.
This simple demo works with GCC 4.6.3:
#include <future>
#include <iostream>
struct Foo
{
Foo() : data(0) {}
void sum(int i) { data +=i;}
int data;
};
int main()
{
Foo foo;
auto f = std::async(&Foo::sum, &foo, 42);
f.get();
std::cout << foo.data << "\n";
}
There are several ways, but I find it's most clear to use a lambda, like this:
int i=42;
Person p;
auto theasync=std::async([&p,i]{ return p.sum(i);});
This creates a std::future. For a complete example of this, I have a full example including a async-capable setup of mingw here:
http://scrupulousabstractions.tumblr.com/post/36441490955/eclipse-mingw-builds
You need to make sure that p is thread safe and that the &p reference is valid until the async is joined. (You can also hold p with a shared pointer, or in c++14, a unique_ptr or even move p into the lambda.)

Call a C-style function address with std::bind and std::function.target using a method from object

I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}

std::bind on member with call operator

This might be a silly and stupid thing to do - however I would like to understand what happens here.
I have the following code:
#include <iostream>
#include <functional>
namespace
{
struct call
{
void operator()() const
{
std::cout << "call::operator()" << std::endl;
}
};
struct dummy
{
dummy() = default;
dummy(const dummy&) = delete;
call member;
};
}
So member essentially would work like any other object method, allowing it to be invoked as:
dummy d;
d.member()
Which would print call::operator().
Now I would like to use bind to do that, the initial implementation looked like this:
int main()
{
dummy d;
auto b = std::bind(&dummy::member, &d);
b();
return 0;
}
This compiles, but nothing is printed. I don't really understand what is happening - the fact that it compiles, but produces no output puzzles me :) surely some magic is going on inside the belly of std::bind, but what?
Here is a link to play with the code:
https://ideone.com/P81PND
Currently, your bind return a member, so b() is d.member.
You would have to call operator () on that:
b()(); // call::operator()
As alternative, you may use any of:
b = std::bind(&call::operator(), &d.member);
b = [&]() {d.member();};
You can also call through a std::reference_wrapper. No need for bind at all.
int main()
{
dummy d;
auto b= std::cref(d.member); // create reference wrapper
b();
return 0;
}

How to get Windows thread pool to call class member function?

I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument