How to use std::async on a member function?

40,214

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

Share:
40,214
Avihai Marchiano
Author by

Avihai Marchiano

Please delete me

Updated on July 09, 2022

Comments

  • Avihai Marchiano
    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
    Stephan Dollberg over 11 years
    It needs to be std::async(&Person::sum, &p, xxx)
  • Johan Lundberg
    Johan Lundberg over 11 years
    & is mandatory for member functions, but optional for free functions.
  • Avihai Marchiano
    Avihai Marchiano over 11 years
    I 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
    Avihai Marchiano over 11 years
    I 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
    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
    Avihai Marchiano over 11 years
    Sorry!!!!!! 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
    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
    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
    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
    Johan Lundberg over 11 years
    That error is not a real error, it's just eclipse being confused about C++11. Just go ahead and compile it!
  • Gunther Piez
    Gunther Piez over 11 years
    @user1495181 The bug is in eclipse. Eclipse has poor C+11 support.
  • Avihai Marchiano
    Avihai Marchiano over 11 years
    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
  • BlazePascal
    BlazePascal over 7 years
    How do you specify the function if it is being overloaded?
  • ashlaban
    ashlaban about 5 years
    The 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
    RARA over 3 years
    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.