Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a packaged_task with a member function?

On the program below, I'm trying to create a packaged_task with a member function:

#include <future>
using namespace std;

struct S
{
    int calc(int& a)
    {
        return a*a;
    }
};

int main()
{
    S s;
    auto bnd = std::bind(&S::calc, s);
    std::packaged_task<int(int&)> task( bnd);
    return 0;
}

Unfortunately the attempt results in an error.

How can this be done?

like image 278
user2286810 Avatar asked Jul 11 '26 05:07

user2286810


2 Answers

by adding up a placeholder like:

auto bnd = std::bind(&S::calc, s, std::placeholders::_1)
like image 139
user2286810 Avatar answered Jul 13 '26 21:07

user2286810


std::bind is quirky.

Replace your use of std::bind with:

template<class T, class Sig>
struct bound_member;

template<class T, class R, class...Args>
struct bound_member<T, R(Args...)> {
  T* t;
  R(T::*m)(Args...);
  R operator()(Args...args)const {
    return (t->*m)(std::forward<Args>(args)...);
};

template<class T, class R, class...Args>
bound_member<T,R(Args...)> bind_member( T* t, R(T::*m)(Args...) ) {
  return {t,m};
}
template<class T, class R, class...Args>
bound_member<T,R(Args...)> bind_member( T& t, R(T::*m)(Args...) ) {
  return {&t,m};
}
template<class T, class R, class...Args>
bound_member<T,R(Args...)> bind_member( T&& t, R(T::*m)(Args...) )
=delete; // avoid lifetime issues?

and now auto bnd = bind_member(s, S::calc); should make your code work.

There are few situations where a lambda isn't a better idea than std::bind, especially by C++14. In C++11, there are some corner cases, but even then I usually prefer to write my own binders without the quirks of std::bind.

like image 38
Yakk - Adam Nevraumont Avatar answered Jul 13 '26 23:07

Yakk - Adam Nevraumont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!