user3060633
user3060633

Reputation:

async with member function

I've a code:

class cabc{
public:
    void pr()
    {
        cout<<"abcdef";
    }
};
int main()
{

    cabc cap;
    auto f = async(cap.pr);
    f.get();
    return 0;
}

This code is not working. I know the same thing can be done using:

auto f = async(&cabc::pr,cap);

This is working. But why the first approach is not working?

Upvotes: 6

Views: 3493

Answers (2)

Ben Collins
Ben Collins

Reputation: 20686

Have a look at the function signature for async:

template< class Function, class... Args>
std::future<typename std::result_of<Function(Args...)>::type>
    async( Function&& f, Args&&... args );

(from cppreference)

It should be apparent that, firstly, whatever Function&& is, it can't be the case that cap.pr and &cabc::pr are both of that type.

More precisely, though, Function&& is supposed to be an rvalue-reference to a function pointer. &cabc::pr is just the syntax for a pointer-to-member-function, and because it's a member function, a pointer to the object itself needs to be the first argument. If cap.pr were a C-style function pointer, then your first sample might work.

Honestly, I'm not sure why your second sample works since you're not passing in a pointer to your object.

There are a number of other answers to similar questions. For example: How to, in C++11, use std::async on a member function?

Upvotes: 1

Anthony Williams
Anthony Williams

Reputation: 68691

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.

Upvotes: 12

Related Questions