отказ: Это описание содержит много специфических функций 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 ошибок компилятора, вот пастбина: http://pastebin.com/2rBQgFNL
Было бы здорово, если бы вы могли объяснить, как это сделать правильно.
Не обязательно для ответа, но даже лучше, будет код для QtConcurrent :: run.
Просто используйте лямбда-выражение.
auto myFunction = [&] { return model->nextStep(simulatedResult->last().molecules, dt); }
Вы также можете использовать std::bind
(увидеть @JonathanWakelyответ), но выражения лямда имхо более универсальные и мощные.
Кроме того, имейте в виду, что чтение и запись в одну и ту же память из нескольких потоков приведет к гонке данных (не передавайте указатели / ссылки на изменяемые данные в потоки QT, если не используется синхронизация).
Вы пытаетесь смешать C ++ 98 bind1st
с C ++ 11 mem_fn
, что невозможно.
bind1st
требует адаптируемая двоичная функция что означает тот, который определяет определенные typedefs, и тот, который принимает именно так два аргумента. Вы не можете использовать это с чем-то, что требует больше двух и продолжать связывать один аргумент за раз.
В C ++ 11 можно обернуть функциональные объекты без этих typedefs, благодаря decltype
и другие новые функции, так что «адаптируемая двоичная функция» теперь бесполезна, и bind1st
бесполезен и не рекомендуется.
Решение состоит в том, чтобы просто использовать функции C ++ 11 вместо bind1st
например, std::bind
или лямбда-выражение.
auto myFunction = std::bind( &ConcreteModel::nextStep, model, simulatedResult->last().molecules, dt);