如何使用成员函数创建 packaged_task?
How do I create a packaged_task with a member function?
在下面的程序中,我试图用一个成员函数创建一个 packaged_task:
#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;
}
不幸的是,尝试导致错误。
如何做到这一点?
通过添加占位符,例如:
auto bnd = std::bind(&S::calc, s, std::placeholders::_1)
std::bind
很古怪。
将您对 std::bind
的使用替换为:
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?
现在 auto bnd = bind_member(s, S::calc);
应该可以使您的代码正常工作。
在某些情况下,lambda 不是比 std::bind
更好的主意,尤其是对于 C++14。在 C++11 中,有一些极端情况,但即便如此,我通常更喜欢编写自己的绑定器,而没有 std::bind
.
的怪癖
在下面的程序中,我试图用一个成员函数创建一个 packaged_task:
#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;
}
不幸的是,尝试导致错误。
如何做到这一点?
通过添加占位符,例如:
auto bnd = std::bind(&S::calc, s, std::placeholders::_1)
std::bind
很古怪。
将您对 std::bind
的使用替换为:
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?
现在 auto bnd = bind_member(s, S::calc);
应该可以使您的代码正常工作。
在某些情况下,lambda 不是比 std::bind
更好的主意,尤其是对于 C++14。在 C++11 中,有一些极端情况,但即便如此,我通常更喜欢编写自己的绑定器,而没有 std::bind
.