原QtConcurrent::run最多只支持传入5个参数,目标为实现任意数量的参数;
不支持传入带&的类型(如:int &xx, class& ...),这情况只能使用指针。
void __task_creator( MainWindow* _this, QString * srcDirPath,QString * m_dstPath
, QFileInfoList *fileList, QThreadPool* m_threadPool
, bool *m_stop, bool *m_pause, bool *m_detailed,
QMutex *m_mutex, QWaitCondition *m_pauseCondition
);
QtConcurrent::run( __task_1, 10 );
QtConcurrent::run( __task_2, 10 );
// 为每个文件创建复制任务
QtConcurrent::run( __task_creator, this
, &m_srcPath, &m_dstPath
, &fileList, &m_threadPool
, &m_stop, &m_pause, &m_detailed
, &m_mutex, &m_pauseCondition );
cpp
#ifndef MY_QTCONCURRENT_H
#define MY_QTCONCURRENT_H
//---------------------------------
/// 新建头文件中加入以下代码即可
/// 使用方法不变
/// 不支持传入带&的类型(如:int &xx, class& ...),这情况只能使用指针
#include <QtConcurrent/QtConcurrent>
namespace QtConcurrent {
// 为C++11提供自定义的index_sequence实现
#if __cplusplus >= 201402L
// C++14及以上使用标准库
namespace detail {
using std::index_sequence;
using std::make_index_sequence;
}
#else
// C++11自定义实现
namespace detail {
template<std::size_t... Is> struct index_sequence {};
template<std::size_t N, std::size_t... Is>
struct make_index_sequence_impl : make_index_sequence_impl<N-1, N-1, Is...> {};
template<std::size_t... Is>
struct make_index_sequence_impl<0, Is...> : index_sequence<Is...> {};
template<std::size_t N>
using make_index_sequence = make_index_sequence_impl<N>;
}
#endif
// 统一的模板实现
template <typename T, typename FunctionPointer, typename... FuncArgs>
struct _StoredFunctorCall : public QtConcurrent::RunFunctionTask<T> {
inline _StoredFunctorCall(FunctionPointer _function, FuncArgs&&... args)
: function(_function), arguments_(std::forward<FuncArgs>(args)...) {}
void runFunctor() override {
// 在C++11中,我们需要用函数重载或模板特化来替代if constexpr
runFunctorImpl(typename std::is_void<T>::type());
}
private:
// 辅助函数:实现参数包展开
template<typename F, typename Tuple, std::size_t... I>
auto apply_impl(F&& f, Tuple&& t, detail::index_sequence<I...>)
-> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
// 主函数:tuple应用函数
template<typename F, typename Tuple>
auto tuple_apply(F&& f, Tuple&& t)
-> decltype(apply_impl(
std::forward<F>(f),
std::forward<Tuple>(t),
detail::make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>()
)) {
return apply_impl(
std::forward<F>(f),
std::forward<Tuple>(t),
detail::make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>()
);
}
// void返回类型的处理
void runFunctorImpl(std::true_type) { // std::true_type 表示 void
// qDebug()<<"std::true_type 表示 void";
tuple_apply(function, arguments_);
}
// 非void返回类型的处理
void runFunctorImpl(std::false_type) { // std::false_type 表示 非void
// qDebug()<<"std::false_type 表示 非void";
this->result = tuple_apply(function, arguments_);
}
public:
FunctionPointer function;
std::tuple<typename std::decay<FuncArgs>::type...> arguments_;
};
// 简化的run函数模板
template <typename T, typename... Args>
QFuture<T> run( T (*functionPointer)(Args...), Args&&... args) {
return (new _StoredFunctorCall<T, T(*)(Args...), Args...>
(functionPointer, std::forward<Args>(args)...))->start();
}
}; // namespace QtConcurrent
//---------------------------------
#endif // MY_QTCONCURRENT_H