简体   繁体   English

C ++:使用mem_fn和bind1st创建一个函数对象

[英]C++: Creating a function object with mem_fn and bind1st

Disclaimer : This description contains a lot of Qt specific functionality. 免责声明 :此描述包含许多Qt特定功能。 This is not necessary to answer the question, I'm just including it to explain the background. 回答这个问题不是必须的,我只是将其包括在内以解释背景。

I need to do some heavy computations in my QT application. 我需要在我的QT应用程序中进行一些繁重的计算。 In order to do this, I would like to use QtConcurrent::run(myFunction) This is Qt's version of async and creates a future, which at some point will contain the result of myFunction . 为了做到这一点,我想使用QtConcurrent::run(myFunction)这是Qt的async版本,并创建一个future,在某些时候它将包含myFunction的结果。

The problem is that the function is both a member function and takes complex parameters. 问题在于该函数既是成员函数,又需要复杂的参数。

I know that you can pass both a function and a pointer to QtConcurrent::run. 我知道您可以将函数和指针都传递给QtConcurrent :: run。 The function will then be invoked on the pointer. 然后将在指针上调用该函数。 You can even provide a list of parameters. 您甚至可以提供参数列表。 But it seems like this list only accepts parameters such as int , double or QString . 但是似乎此列表仅接受诸如intdoubleQString

Actual Question: 实际问题:

I would like to convert this line of code: 我想转换以下代码行:

model->nextStep(simulatedResult->last().molecules, dt)

into 进入

myFunction()

That means I need to 这意味着我需要

  1. bind the pointer to the function 将指针绑定到函数
  2. bind the arguments to the function 将参数绑定到函数

This is my code so far: 到目前为止,这是我的代码:

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);

Unfortunately this doesn't work. 不幸的是,这不起作用。 There are 18 compiler errors, here is the pastebin: http://pastebin.com/2rBQgFNL 有18个编译器错误,这是pastebin: http : //pastebin.com/2rBQgFNL

It would be great, if you could explain how to do this properly. 如果您能解释如何正确执行此操作,那就太好了。 Not necessary for an answer, but even better, would be code for QtConcurrent::run. 一个答案不是必需的,但更好的是QtConcurrent :: run的代码。

Simply use a lambda expression. 只需使用lambda表达式。

auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }

You could also use std::bind (see @JonathanWakely 's answer), but lamda expressions are imho more universal and powerful. 您也可以使用std::bind (请参阅@JonathanWakely的答案),但是lamda表达式更加通用和强大。

Also, keep in mind that reading and writing to the same memory from multiple threads will result in a data race (don't pass pointers/references to mutable data to the QT threads unless synchronization is used). 另外,请记住,从多个线程读取和写入同一内​​存将导致数据争用(除非使用同步,否则请勿将指向可变数据的指针/引用传递给QT线程)。

You're trying to mix the C++98 bind1st with the C++11 mem_fn , which isn't possible. 您正在尝试将C ++ 98 bind1st与C ++ 11 mem_fn混合使用。

bind1st requires an adaptable binary function which means one that defines certain typedefs, and one that takes exactly two arguments. bind1st需要一个适应性强的二元函数 ,这意味着一个定义了某些类型定义,和一个取恰好两个参数。 You can't use it with something that requires more than two and keep binding one argument at a time. 您不能将它与需要两个以上的东西一起使用,并且一次绑定一个参数。

In C++11 it is possible to wrap function objects without those typedefs, thanks to decltype and other new features, so "adaptable binary function" is a useless concept now, and bind1st is useless and deprecated. 在C ++ 11中,由于使用了decltype和其他新功能,可以包装没有那些typedef的函数对象,因此“可适应的二进制函数”现在是一个无用的概念,而bind1st则是无用和不推荐使用的。

The solution is simply to use C++11 features instead of bind1st , eg std::bind or a lambda expression. 解决方案是简单地使用C ++ 11功能而不是bind1st ,例如std::bind或lambda表达式。

auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM