「タスク」クラスを実装したいと考えています。このクラスには、関数ポインターとそれに渡す引数を格納できます。std::bind() のように。引数の保存方法について質問があります。
class BaseTask {
public:
virtual ~BaseTask() {}
virtual void run() = 0;
};
template<typename ... MTArg>
class Task : public BaseTask {
public:
typedef void (*RawFunction)(MTArg...);
Task(RawFunction rawFunction, MTArg&& ... args) : // Q1: MTArg&& ... args
rawFunction(rawFunction),
args(std::make_tuple(std::forward<MTArg>(args)...)) {} // Q2: std::make_tuple(std::forward<MTArg>(args)...)
virtual void run() {
callFunction(GenIndexSequence<sizeof...(MTArg)>()); // struct GenIndexSequence<count> : IndexSequence<0, ..., count-1>
}
private:
template<unsigned int... argIndexs>
inline void callFunction() {
rawFunction(std::forward<MTArg>(std::get<argIndexs>(args))...);
}
private:
RawFunction rawFunction;
std::tuple<MTArg...> args; // Q3: std::tuple<MTArg...>
};
Q1: MTArg の後に && は必要ですか?
Q2: この方法で引数を初期化するのは正しいですか?
Q3: 引数の型は正しいですか?
std::tuple<special_decay_t<MTArg>...>
これによると:http://en.cppreference.com/w/cpp/utility/tuple/make_tuple
//質問終わり
Task は次のように使用できます。
void fun(int i, const int& j) {} BaseTask* createTask1() { return new Task<int, const int&>(&fun, 1, 2); // "2" must not be disposed at the time of task.run(), so inside Task "2" should be store as "int", not "const int&" } BaseTask* createTask2(const int& i, const int& j) { return new Task<int, const int&>(&fun, i, j); // "j" must not be disposed at the time of task.run(), so inside Task "j" should be store as "int", not "const int&" } void test(){ createTask1()->run(); createTask2(1, 2)->run(); }
task は 1 回しか実行されません。つまり、0 回または 1 回です。