Pass contents of tuple as arguments to variational function

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 ...

0
source share
1 answer

It should be equivalent, but the only way to make sure that you must check it with the compiler.

Note that instead of std::function you can use std::function , for example, something like:

 template<typename ...T_arguments> class Task : public TaskCaller { std::function<bool (T_arguments&...)> functor; public: Task (bool (*func)(T_arguments&...), T_arguments... arguments) : functor(std::bind(func, arguments...)) {} bool dispatch() { return functor(); } // ... 

Or better yet, let the user pass the std::function to:

 class Task : public TaskCaller { std::function<bool ()> functor; public: Task(std::function<bool ()> func) : functor(func) {} // ... 

This allows the user to choose what to transfer, instead of forcing him to use free functions or static member functions.

+3
source

Source: https://habr.com/ru/post/1395372/


All Articles