C++:使用 mem_fn 和 bind1st 创建一个函数对象
C++: Creating a function object with mem_fn and bind1st
免责声明:本说明包含大量 Qt 特定功能。这不是回答问题所必需的,我只是将其包括在内以解释背景。
我需要在我的 QT 应用程序中进行一些繁重的计算。
为了做到这一点,我想使用 QtConcurrent::run(myFunction)
这是 Qt 的异步版本并创建一个未来,它在某些时候将包含 myFunction
.
的结果
问题在于该函数既是成员函数又采用复杂参数。
我知道您可以将函数和指针都传递给 QtConcurrent::run。然后将在指针上调用该函数。您甚至可以提供参数列表。但似乎这个列表只接受 int
、double
或 QString
.
等参数
真题:
我想转换这行代码:
model->nextStep(simulatedResult->last().molecules, dt)
进入
myFunction()
这意味着我需要
- 将指针绑定到函数
- 将参数绑定到函数
到目前为止,这是我的代码:
auto memfun=std::mem_fn(&ConcreteModel::nextStep);
auto memfun_bound_to_model=std::bind1st(memfun,model);
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules);
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt);
不幸的是,这不起作用。
有 18 个编译器错误,这里是 pastebin:http://pastebin.com/2rBQgFNL
如果您能解释如何正确执行此操作,那就太好了。
答案不是必需的,但更好的是 QtConcurrent::run.
的代码
只需使用 lambda expression.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
您也可以使用 std::bind
(see 的答案),但恕我直言,lamda 表达式更通用、更强大。
此外,请记住,从多个线程读取和写入同一内存将导致数据竞争(除非使用同步,否则不要将 pointers/references 传递给 QT 线程的可变数据)。
您试图将 C++98 bind1st
与 C++11 mem_fn
混合使用,这是不可能的。
bind1st
需要一个 adaptable binary function ,这意味着一个定义了某些类型定义,一个接受 恰好 两个参数。你不能将它与需要两个以上的东西一起使用,并且一次只能绑定一个参数。
在 C++11 中,由于 decltype
和其他新功能,可以在没有这些类型定义的情况下包装函数对象,因此 "adaptable binary function" 现在是一个无用的概念,并且 bind1st
无用且已弃用。
解决方案是简单地使用 C++11 功能而不是 bind1st
,例如std::bind
或 lambda 表达式。
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);
免责声明:本说明包含大量 Qt 特定功能。这不是回答问题所必需的,我只是将其包括在内以解释背景。
我需要在我的 QT 应用程序中进行一些繁重的计算。
为了做到这一点,我想使用 QtConcurrent::run(myFunction)
这是 Qt 的异步版本并创建一个未来,它在某些时候将包含 myFunction
.
问题在于该函数既是成员函数又采用复杂参数。
我知道您可以将函数和指针都传递给 QtConcurrent::run。然后将在指针上调用该函数。您甚至可以提供参数列表。但似乎这个列表只接受 int
、double
或 QString
.
真题:
我想转换这行代码:
model->nextStep(simulatedResult->last().molecules, dt)
进入
myFunction()
这意味着我需要
- 将指针绑定到函数
- 将参数绑定到函数
到目前为止,这是我的代码:
auto memfun=std::mem_fn(&ConcreteModel::nextStep);
auto memfun_bound_to_model=std::bind1st(memfun,model);
auto memfun_bound_result=std::bind1st(memfun_bound_to_model,simulatedResult->last().molecules);
auto memfun_bound_dt=std::bind1st(memfun_bound_result,dt);
不幸的是,这不起作用。 有 18 个编译器错误,这里是 pastebin:http://pastebin.com/2rBQgFNL
如果您能解释如何正确执行此操作,那就太好了。 答案不是必需的,但更好的是 QtConcurrent::run.
的代码只需使用 lambda expression.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
您也可以使用 std::bind
(see
此外,请记住,从多个线程读取和写入同一内存将导致数据竞争(除非使用同步,否则不要将 pointers/references 传递给 QT 线程的可变数据)。
您试图将 C++98 bind1st
与 C++11 mem_fn
混合使用,这是不可能的。
bind1st
需要一个 adaptable binary function ,这意味着一个定义了某些类型定义,一个接受 恰好 两个参数。你不能将它与需要两个以上的东西一起使用,并且一次只能绑定一个参数。
在 C++11 中,由于 decltype
和其他新功能,可以在没有这些类型定义的情况下包装函数对象,因此 "adaptable binary function" 现在是一个无用的概念,并且 bind1st
无用且已弃用。
解决方案是简单地使用 C++11 功能而不是 bind1st
,例如std::bind
或 lambda 表达式。
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);