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.
async, it's just how the language works (or not work).cap.pris not a function.cap.pr(arg)means something like "callcabc::proncapwith argumentarg".cap.prby itself doesn't make sense.std::mem_fnand it is internally used bystd::asyncto make theasync(&a::b, c)syntax work.