Search code examples
c++qtconcurrencyfunctional-programmingmem-fun

C++: Creating a function object with mem_fn and bind1st


Disclaimer: This description contains a lot of Qt specific functionality. 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. 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.

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. 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.

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

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.


Solution

  • Simply use a lambda expression.

    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.

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