How to use std::async on a member function?
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";
}
C++ use async with member function
There are a number of typos in your code, but what I think you are trying to get at is that you have the wrong syntax for a pointer to a member function. It should be &class_name::function_name
. Also, you need to pass this
as before any other parameters to emplace_back
, and the last parameter should be work_list
, not work_list [i]
.
So, all-in-all, that gives us:
v_async.emplace_back(std::async(std::launch::async, &Worker::WorkA, this, i, work_list));
Then, it compiles
std::async call of member function
The problem appears to be that it won't play nice with member functions. Perhaps you can std::bind
the member function to your object first, before passing it to std::async
:
auto func = std::bind(&Foo::bar, this, std::placeholders::_1);
auto handle = std::async(std::launch::async, func, 0);
std::async with non static member functions
You can use a lambda like following, using a policy*
auto handle = std::async(std::launch::async, [&ptr](){
return ptr->foo(); // Ofcourse make foo public in your snippet
});
auto res = handle.get();
*Not necessarily required
Class and std::async on class member in C++
do_rand_stf
is a non-static member function and thus cannot be called without a class instance (the implicit this
parameter.) Luckily, std::async
handles its parameters like std::bind
, and bind
in turn can use std::mem_fn
to turn a member function pointer into a functor that takes an explicit this
parameter, so all you need to do is to pass this
to the std::async
invocation and use valid member function pointer syntax when passing the do_rand_stf
:
auto hand=async(launch::async,&A::do_rand_stf,this,i,j);
There are other problems in the code, though. First off, you use std::cout
and std::endl
without #include
ing <iostream>
. More seriously, std::future
is not copyable, only movable, so you cannot push_back
the named object hand
without using std::move
. Alternatively, just pass the async
result to push_back
directly:
ran.push_back(async(launch::async,&A::do_rand_stf,this,i,j));
async with member function
cap.pr
is an incomplete member function call expression. You must follow it with parentheses containing the appropriate function arguments to make a valid C++ expression.
You can't therefore pass cap.pr
to std::async
or any other function.
To pass a member function to std::async
you need to use the syntax you found:
auto f=std::async(&capc::pr,cap);
Though in this case, you need to be aware that the cap
object is copied. You could also use
auto f=std::async(&capc::pr,&cap);
to just pass a pointer to cap
.
If the pointer-to-member-function syntax is unwelcome then you can use a lambda:
auto f=std::async([&]{cap.pr();});
This isn't quite the same: it doesn't pass the member function pointer and object pointer to std::async
, it passes a lambda object containing a reference to cap
that calls its pr
member function directly. However, the result is essentially the same.
Can't do async run member function in other class
I tried to fix your code and came up with a version that is working. You have a lot of unecessary cluttering in there. Also your code will leak the workset pointer. As pointed out in the comments the main mistake was the &workset
which created a "ref to pointer" where all you need was the pointer itself. You should avoid the plain pointers altogether. This is what I came up with, hope it helps:
#include <vector>
#include <future>
#include <iostream>
class Work
{
public:
void doWork(int A){
std::cout << "I got " << A << std::endl;
}
};
class Worker
{
public:
void Work_MP(){
std::vector< std::future<void> > v_async;
v_async.reserve( 8 );
for( size_t i = 0; i < 8; ++i ){
std::shared_ptr<Work> workset = std::make_shared<Work>();
v_async.emplace_back( std::async( std::launch::async, &Work::doWork, workset, i ) );
}
}
};
int main ()
{
Worker worker;
worker.Work_MP();
return 0;
}
As you can see I inlined the function definition for briefness. Converted the plain pointer to shared pointer and removed unused vars.
See it in action here: https://onlinegdb.com/vFQo8R1rA
How do I pass a function from another class while calling std::async from a function of different class?
As per the comment if the member function you want to run using std::async is CameraToBEV::process
then the parameter passed immediately after &CameraToBEV::process
should be a pointer to a valid CameraToBEV
instance.
In addition, std::async
will, by default, pass parameters by value. However the function you're calling has the signature...
cv::Mat process(json&, std::vector<Point2f> = { Point2f(765,57), Point2f(1860,57), Point2f(27, 1000) ,Point2f(1800, 1000) }, Point2f=Point2f(1920,1080), Point2f=Point2f(1920, 1080));
so it expects the first parameter as a non-const reference to a json
object. The call to std::async
should therefore be (untested)...
processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process, &cbevObj, std::ref(jsonObjects[i])));
(Note the use of std::ref
)
std::async with a member function, holding another meber fucntion as an argument
fa
and fb
don't fully "compile" until you actually call them - the function call operators aren't instantiated till then, it seems. Once you call, you'll realize that fb
is invalid, i.e. fb()
won't compile. As soon as you fix that, the async
call will work :)
As a further hint, observe that std::bind
is subtly broken and not recommended for new code. You'd be better served with lambdas (they'd actually work here!).
How is bind broken? Like so:
std::bind(&Test::Func1, &te, a, b, fa)(); // won't compile
But:
using FnArg = std::function<void(std::vector<double> const&, int)>;
fb = std::bind(&Test::Func1, &te, a, b, FnArg(fa));
fb(); // compiles OK
So, you'd be best served by forgetting about std::bind
's existence, and use lambdas:
#include <functional>
#include <future>
#include <string>
#include <vector>
class Test
{
public:
using FnArg = std::function<void(std::vector<double> const&, int)>;
void Func1(std::string const&, std::string const&, FnArg) {}
std::vector<double> Func2(std::vector<double> const&, size_t const) {}
};
int main()
{
Test te;
std::vector<double> vd;
std::string a, b;
auto fa = [&te](const auto &a, auto b){ return te.Func2(a, b); };
auto fb = [=,&te](){ return te.Func1(a, b, fa); };
fa(vd, 1);
fb();
auto fab = std::async(std::launch::async, fb);
fab.wait();
}
Feel free to mess with it online.
Related Topics
Difference Between a Virtual Function and a Pure Virtual Function
Which Is Better Option to Use for Dividing an Integer Number by 2
Write Applications in C or C++ for Android
Is Std::Vector Copying the Objects with a Push_Back
Benchmarking (Python VS. C++ Using Blas) and (Numpy)
Should I Learn C Before Learning C++
How to Set Up Googletest as a Shared Library on Linux
How to Identify Platform/Compiler from Preprocessor MACros
What Do Each Memory_Order Mean
What Does Flushing the Buffer Mean
How to Append an Int to a String in C++
When Should I Use C++14 Automatic Return Type Deduction
How Does the Modulus Operator Work
How to Pre-Allocate Memory for a Std::String Object
How to Avoid Repeating the Class Name in the Implementation File