How to use std::async on a member function?
Solution 1
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";
}
Solution 2
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.)
Comments
-
Avihai Marchiano almost 2 years
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.
-
Stephan Dollberg over 11 yearsIt needs to be
std::async(&Person::sum, &p, xxx)
-
Johan Lundberg over 11 years& is mandatory for member functions, but optional for free functions.
-
Avihai Marchiano over 11 yearsI tried but got error - Invalid arguments ' Candidates are: std::__async_sfinae_helper<std::decay<#0>::type,#0,#1 ...>::type async(#0 &&, #1 && ...) std::future<std::result_of<#0 (#1 ...)>::type> async(enum std::launch, #0 &&, #1 && ...) '
-
Avihai Marchiano over 11 yearsI tried but got error - Invalid arguments ' Candidates are: std::__async_sfinae_helper<std::decay<#0>::type,#0,#1 ...>::type async(#0 &&, #1 && ...) std::future<std::result_of<#0 (#1 ...)>::type> async(enum std::launch, #0 &&, #1 && ...) '
-
juanchopanza over 11 years@user1495181 which compiler are you using? It could be that
std::async
isn't properly implemented in your compiler. -
Avihai Marchiano over 11 yearsSorry!!!!!! The error is just eclipse error, the build is passed for your example , but eclipse show errors. However for this example - en.cppreference.com/w/cpp/thread/async there is no errors in eclipse . errors only show in eclipse for your example
-
juanchopanza over 11 years@user1495181 OK, I see. Eclipse can be a pain with C++11. I still haven't managed to get rid of all the false error warnings.
-
Avihai Marchiano over 11 years@juanchopanza i add the support for c++11 and i already use in c++11 stuff , i dont know why it dosnt love this. can you advice what is why eclipse accept the way in this link en.cppreference.com/w/cpp/thread/async , but not the way that you suggested?
-
juanchopanza over 11 years@user1495181 I'm not an eclipse expert. The main difference between the codes is that yours uses member functions, and cppreference.com's example uses a non-member, or free, function.
-
Johan Lundberg over 11 yearsThat error is not a real error, it's just eclipse being confused about C++11. Just go ahead and compile it!
-
Gunther Piez over 11 years@user1495181 The bug is in eclipse. Eclipse has poor C+11 support.
-
Avihai Marchiano over 11 yearsYep , i figure out that this is eclipse problem . See my comment on juanchopanza answer. Some of my code is c++11 and eclipse dosnt has problem with it. I didnt figure out why it has problem with async is certain ways . in this way async work - en.cppreference.com/w/cpp/thread/async
-
BlazePascal over 7 yearsHow do you specify the function if it is being overloaded?
-
ashlaban about 5 yearsThe notes section on this page imply that your snippet will actually not run asynchronously. Is it enough to change the call to
std::async(std::launch::async, std::move([&p,i]{ return p.sum(i);}));
? -
RARA over 3 yearsI was able to pass the object by value to std::async and it stilled worked. I thought it was only supposed to work with a reference to the object only.