我使用C ++ 0x已经有一段时间了,现在我想使用可变参数模板和元组来实现类“任务”。我将把Task对象传递给新创建的线程(使用pthread)。任务类将包含函数的函数指针,该函数指针应该在该函数的线程和参数内调用,简化代码:
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...);
};
我用来将元组解包为函数参数的代码:
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...);
}
};
用例:
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);
}
我还没有测试过这段代码,但这只是想法。
现在我想知道TupleUnpack类将如何影响最终代码。根据我的知识,Task :: dispatch函数的最终实现(在编译器解析模板之后)将等同于:
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));
}
正确?
此外,元组本身和std :: get()应该在最终代码中“消失”并且不提供运行时开销(according to Boost documentation)。
也许有更好的方法来解决我的问题...
答案 0 :(得分:3)
它应该是等价的,但唯一可以确定的方法是使用你正在使用的编译器进行测试。
请注意,您可以使用std::function
代替std::bind
,例如类似的东西:
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();
}
// ...
或者更好的是,让用户传递std::function
in:
class Task : public TaskCaller {
std::function<bool ()> functor;
public:
Task(std::function<bool ()> func) : functor(func) {}
// ...
允许用户选择要传递的内容,而不是强迫他使用自由函数或静态成员函数。