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

时间:2015-09-17 15:17:15

标签: c++ qt concurrency functional-programming mem-fun

免责声明:此说明包含许多特定于Qt的功能。这不是回答这个问题的必要条件,我只是将它包括在内以解释背景。

我需要在QT应用程序中进行一些繁重的计算。 为了做到这一点,我想使用QtConcurrent::run(myFunction)这是Qt的异步版本并创建了一个未来,在某些时候它将包含myFunction的结果。

问题是该函数既是成员函数又是复杂参数。

我知道你可以传递一个函数和一个指向QtConcurrent :: run的指针。然后将在指针上调用该函数。您甚至可以提供参数列表。但似乎此列表仅接受intdoubleQString等参数。

实际问题:

我想转换这行代码:

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

myFunction()

这意味着我需要

  1. 将指针绑定到函数
  2. 将参数绑定到函数
  3. 到目前为止,这是我的代码:

    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。

    的代码

2 个答案:

答案 0 :(得分:4)

只需使用lambda expression.

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

您也可以使用std::bind(请参阅@JonathanWakely的答案),但lamda表达式更具普遍性和强大功能。

另外,请记住,从多个线程读取和写入相同的内存将导致数据争用(除非使用同步,否则不要将指向可变数据的指针/引用传递给QT线程)。

答案 1 :(得分:4)

您正试图将C ++ 98 bind1st与C ++ 11 mem_fn混合在一起,这是不可能的。

bind1st需要一个adaptable binary function,这意味着一个定义某些typedef,另一个需要完全两个参数。你不能将它用于需要两个以上的东西,并且一次只能绑定一个参数。

在C ++ 11中,由于decltype和其他新功能,可以在没有这些typedef的情况下包装函数对象,因此"自适应二进制函数"现在是一个无用的概念,而bind1st是无用的并且已被弃用。

解决方案只是使用C ++ 11功能而不是bind1st,例如std::bind或lambda表达式。

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