46

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.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Avihai Marchiano
  • 3,837
  • 3
  • 38
  • 55
  • possible duplicate of [Start thread with member function](http://stackoverflow.com/questions/10673585/start-thread-with-member-function) – Stefan Gehrig Dec 02 '12 at 18:54

2 Answers2

51

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";
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 1
    It needs to be `std::async(&Person::sum, &p, xxx)` – Stephan Dollberg Dec 02 '12 at 12:09
  • 3
    & is mandatory for member functions, but optional for free functions. – Johan Lundberg Dec 02 '12 at 12:10
  • I tried but got error - Invalid arguments ' Candidates are: std::__async_sfinae_helper::type,#0,#1 ...>::type async(#0 &&, #1 && ...) std::future::type> async(enum std::launch, #0 &&, #1 && ...) ' – Avihai Marchiano Dec 02 '12 at 12:25
  • @user1495181 which compiler are you using? It could be that `std::async` isn't properly implemented in your compiler. – juanchopanza Dec 02 '12 at 12:59
  • Sorry!!!!!! The error is just eclipse error, the build is passed for your example , but eclipse show errors. However for this example - http://en.cppreference.com/w/cpp/thread/async there is no errors in eclipse . errors only show in eclipse for your example – Avihai Marchiano Dec 02 '12 at 13:09
  • @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. – juanchopanza Dec 02 '12 at 13:12
  • @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 http://en.cppreference.com/w/cpp/thread/async , but not the way that you suggested? – Avihai Marchiano Dec 02 '12 at 13:14
  • @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. – juanchopanza Dec 02 '12 at 13:16
  • @user1495181 The bug is in eclipse. Eclipse has poor C+11 support. – Gunther Piez Dec 02 '12 at 19:03
  • How do you specify the function if it is being overloaded? – BlazePascal Aug 30 '16 at 22:58
  • I 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. – Simon Dec 26 '20 at 02:54
  • std async is horrid, because you can't install a thread pool to be used with it. if you could it would be fine. – Erik Aronesty Dec 14 '22 at 13:37
20

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

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
  • I tried but got error - Invalid arguments ' Candidates are: std::__async_sfinae_helper::type,#0,#1 ...>::type async(#0 &&, #1 && ...) std::future::type> async(enum std::launch, #0 &&, #1 && ...) ' – Avihai Marchiano Dec 02 '12 at 12:37
  • 1
    That error is not a real error, it's just eclipse being confused about C++11. Just go ahead and compile it! – Johan Lundberg Dec 02 '12 at 14:44
  • Yep , 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 – Avihai Marchiano Dec 02 '12 at 21:22
  • The notes section on [this page](https://en.cppreference.com/w/cpp/thread/async) 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);}));`? – ashlaban Mar 05 '19 at 13:07