Je joue avec C++ 0x depuis un certain temps et maintenant je veux utiliser des templates et des tuple variadiques pour implémenter la classe "Task". Je vais passer des objets Task dans des threads nouvellement créés (en utilisant pthread). classe Task contiendra pointeur de fonction à l'autre qui devrait être appelé à l'intérieur du fil et des arguments pour cette fonction, le code simplifié:Passage du contenu du tuple en tant qu'arguments de la fonction variadique
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...);
};
et le code que j'utilise pour décompresser tuple dans les arguments de la fonction:
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...);
}
};
utilisation 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);
}
Je n'ai pas encore testé ce code, c'est seulement une idée.
Maintenant, je me demande comment la classe TupleUnpack aura un impact sur le code final. Selon ma connaissance mise en œuvre finale de la fonction Tâche :: dispatch (après modèles parse du compilateur) sera équivalent de:
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));
}
droit?
De plus le tuple lui-même et std :: get() devraient "disparaître" dans le code final et ne fournir aucun temps d'exécution (according to Boost documentation).
Peut-être qu'il ya une meilleure façon de résoudre mon problème ...