I have been playing with C ++ 0x for some time, and now I want to use variable templates and tuples to implement the Task class. I am going to pass task objects to newly created threads (using pthread). The Task class will contain a pointer to a function that should be called inside the stream and the arguments for this function, simplified code:
class TaskCaller { // ... virtual bool dispatch (void); }; template<typename ...T_arguments> Task : public TaskCaller { public: // ... Task (bool (*function) (T_arguments&...), T_arguments... arguments) : function_arguments_tuple (arguments...), function (function) { // ... } bool dispatch (void) { return TupleUnpack<sizeof ...(T_arguments)>::unpack (this->function, this->function_arguments_tuple); } private: std::tuple<T_arguments&...> function_arguments_tuple; bool (*function) (T_arguments...); };
And the code that I use to unpack the tuple into function arguments:
template<unsigned int i> class TupleUnpack { public: template<typename T_return_type, typename ...T_tuple_arguments, typename ...T_function_arguments> inline static T_return_type unpack (T_return_type (*function) (T_tuple_arguments&...), std::tuple<T_tuple_arguments...>& arguments_tuple, T_function_arguments ...function_arguments) { return TupleUnpack<i-1>::unpack (function, arguments_tuple, std::get<i-1> (arguments_tuple), function_arguments...); } }; template<> class TupleUnpack<0> { public: template<typename T_return_type, typename ...T_tuple_arguments, typename ...T_function_arguments> inline static T_return_type unpack (T_return_type (*function) (T_tuple_arguments&...), std::tuple<T_tuple_arguments...>& arguments_tuple, T_function_arguments ...function_arguments) { return function (function_arguments...); } };
Use Case:
bool task_function (Foo &foo, Bar &bar) { // ... return true; } void* thread_function (void* argument) { Task* task ((Task*) argument); task->dispatch (); delete task; pthread_exit (0); } void function (void) { Foo foo (1, 2, 3); Bar bar (1, 2, 3); Task<Foo, Bar>* task = new Task (task_function, std::move (foo) std::move (bar)); pthread_t thread_id; pthread_create (&thread_id, task_function, task); }
I have not tested this code yet, this is just an idea and an idea.
Now I'm wondering how the TupleUnpack class will affect the final code. To my knowledge, the final implementation of the Task :: dispatch function (after compiler syntax templates) will be equivalent to:
template<typename ...T_arguments> static bool Task<...T_arguments>::dispatch (void) { return this->function (std::get<0> (this->function_arguments_tuple), std::get<1> (this->function_arguments_tuple), ..., std::get<n> (this->function_arguments_tuple)); }
right?
In addition, the tuple itself and std :: get () should "disappear" in the final code and not provide overhead at run time (according to the Boost documentation) .
Maybe there is a better way to solve my problem ...