qt — C ++: создание функционального объекта с помощью mem_fn и bind1st

отказ: Это описание содержит много специфических функций Qt. Это не обязательно, чтобы ответить на вопрос, я просто включаю его, чтобы объяснить фон.

Мне нужно сделать несколько тяжелых вычислений в моем приложении QT.
Для этого я бы хотел использовать QtConcurrent::run(myFunction) Это версия асинхронного Qt и создает будущее, которое в какой-то момент будет содержать результат myFunction,

Проблема в том, что эта функция является одновременно функцией-членом и принимает сложные параметры.

Я знаю, что вы можете передать как функцию, так и указатель на QtConcurrent :: run. Функция будет вызываться по указателю. Вы даже можете предоставить список параметров. Но кажется, что этот список принимает только такие параметры, как int, double или же QString,

Актуальный вопрос:

Я хотел бы преобразовать эту строку кода:

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

в

myFunction()

Это означает, что мне нужно

  1. привязать указатель к функции
  2. привязать аргументы к функции

Это мой код до сих пор:

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.

1

Решение

Просто используйте лямбда-выражение.

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

Вы также можете использовать std::bind (увидеть @JonathanWakelyответ), но выражения лямда имхо более универсальные и мощные.

Кроме того, имейте в виду, что чтение и запись в одну и ту же память из нескольких потоков приведет к гонке данных (не передавайте указатели / ссылки на изменяемые данные в потоки QT, если не используется синхронизация).

4

Другие решения

Вы пытаетесь смешать 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);
4

По вопросам рекламы [email protected]