如何将QRunnable子类化以运行任何成员函数?

时间:2019-07-03 01:56:28

标签: c++ qt

给定一定的延迟,我想通过向QThreadPool全局实例提供QRunnable来运行X类的成员函数。 QRunnable子类的构造函数将使用延迟int,实例指针,成员函数指针和函数参数。

我想知道应该如何进行。我有以下代码,我对如何解决这个问题有些困惑。

template<typename I, typename F, typename ...Args>
class Task : public QRunnable{

public:
    Task(int delay, I &&instance_ptr, F &&func_ptr, Args &&... args):
        delay(delay),
        instance_ptr(std::forward<I>(instance_ptr)),
        func_ptf(std::forward<F>(func_ptr)),
        args_tuple(std::forward<Args>(args)...)
    {}

    void run() override
    {
        QThread::sleep(delay);

        (instance_ptr->*func_ptr)(args_tuple) // This is where i don't know how to unpack the tuple
    }
private:
    int delay;
    I instance_ptr;
    F func_ptr;
    std::tuple<Args...> args_tuple;

}

1 个答案:

答案 0 :(得分:0)

如果您拥有C ++ 17,则可以使用std::apply

如果您使用的是C ++的早期版本,则必须自己弄技巧拆开元组的包装。如果您搜索如何使用元组调用函数,则Internet上有很多这样的函数。

std::apply中的documentation page,还为您提供了一种可能的实现方式:

namespace detail {
template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>)
{
    return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
}  // namespace detail

template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t)
{
    return detail::apply_impl(
        std::forward<F>(f), std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
}