Передайте QTimer :: singleShot в std :: async, используя std :: bind - PullRequest
0 голосов
/ 09 мая 2018

Следующий код запускает неблокирующий таймер, который запускает функцию myFunc через одну секунду:

MyClass.h:

std::future<void> timer_future_;

MyClass.cpp:

timer_future_ = std::async(

        std::launch::async,
        [this] { QTimer::singleShot(1000,
                                    [this] {this->myFunc();}
                                    );
               }
    );

Я хотел бы заменить лямбда-функции на std::function с. Я успешно заменил вторую лямбду следующим образом:

timer_future_ = std::async(

        std::launch::async,
        [this] { QTimer::singleShot(1000, 
                                    std::bind(&MyClass::myFunc, this)
                                    );
               }
    );

Как теперь я могу заменить первую лямбду другим std::bind() вызовом?

Обратите внимание, что функция QTimer::singleShot из библиотек Qt; его документация здесь . Его прототип:

void QTimer::singleShot(int msec, Functor functor)

Согласно этому вопросу определение типа Functor можно найти в QObject.h. Там написано:

template <class FunctorT, class R, typename... Args> class Functor { /*...*/ }

После некоторых исследований я понимаю, что std::bind(), который заменит первую лямбду, должен учитывать следующее:

Я предпринял несколько неудачных попыток, последняя из которых была:

timer_future_ = std::async(
        std::launch::async,
        std::bind( ( void(*) (int, Functor<const std::function<void(void)>,void>) )&QTimer::singleShot,
                  1000,
                  std::bind(&MyClass::myFunc, this)
                  )
);

Для этого кода компилятор MSVC вернул сообщение об ошибке

error: C2059: syntax error: ')'

в третьей строке.

Почему бы мне просто не использовать лямбды, которые уже работают? Ответ прост: вместо этого попытка использовать std :: bind () учит меня различным возможностям языка C ++. и как их использовать.


РЕДАКТИРОВАТЬ: Код, который реализует ответ Куба Обер:

QTimer::singleShot(1000, [this] {
    timer_future_ = std::async(
                std::launch::async,
                std::bind(&MyClass::myFunc, this)
                );
});

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Таймеру требуется цикл обработки событий, и std::async вызовет его в рабочем потоке, в котором нет работающего цикла обработки событий. Я спрашиваю, почему вы хотите это сделать?

Если вы хотите запустить что-то в рабочем потоке после задержки, запустите таймер в потоке, в котором есть цикл обработки событий, и запустите асинхронное действие из этого таймера.

0 голосов
/ 09 мая 2018

Считать открывающие и закрывающие скобки и добавить точку с запятой

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...