Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 传递元组';s内容作为变量函数参数_C++_Templates_C++11_Tuples_Variadic Functions - Fatal编程技术网

C++ 传递元组';s内容作为变量函数参数

C++ 传递元组';s内容作为变量函数参数,c++,templates,c++11,tuples,variadic-functions,C++,Templates,C++11,Tuples,Variadic Functions,我用C++0x玩了一段时间,现在我想使用可变模板和元组来实现类“Task”。我将把任务对象传递到新创建的线程中(使用pthread)。任务类将包含指向应在线程内调用的函数的函数指针和此函数的参数,简化代码: class TaskCaller { // ... virtual bool dispatch (void); }; template<typename ...T_arguments> Task : public TaskCaller { pub

我用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...);
};
类任务调用程序
{
// ...
虚拟布尔调度(void);
};
模板任务:
公共任务调用程序
{
公众:
// ...
任务(bool(*函数)(T_参数和…),
T_参数…参数):
函数\参数\元组(参数…),
功能(功能)
{
// ...
}
布尔调度(无效)
{
返回TupleUnpack::unpack(this->function,this->function\u arguments\u tuple);
}
私人:
std::tuple函数\参数\ tuple;
bool(*函数)(T_参数…);
};
以及用于将元组解压为函数参数的代码:

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...);
            }          
};
模板类TupleUnpack
{
公众:
模板
内联静态T_返回类型解包(T_返回类型(*函数)(T_元组参数&…),
std::tuple和arguments\u tuple,
函数参数…函数参数)
{
返回TupleUnpack::unpack(函数,参数,std::get(参数,参数),函数,参数…);
}                       
};
模板类TupleUnpack
{
公众:
模板
内联静态T_返回类型解包(T_返回类型(*函数)(T_元组参数&…),
std::tuple和arguments\u tuple,
函数参数…函数参数)
{
返回函数(函数参数…);
}          
};
用例:

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);
}
bool任务函数(Foo&Foo,Bar&Bar)
{
// ...
返回true;
}
void*线程函数(void*参数)
{
任务*任务((任务*)参数);
任务->调度();
删除任务;
pthread_退出(0);
}
空函数(void)
{
富富(1,2,3),;
棒材(1,2,3);
Task*Task=新任务(Task_函数,std::move(foo)std::move(bar));
pthread_t thread_id;
pthread_create(&thread_id,task_函数,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));
}
模板静态bool任务::分派(void)
{
返回此->函数(std::get(this->function_arguments_tuple),std::get(this->function_arguments_tuple),…,std::get(this->function_arguments_tuple));
}
对吧?

此外,tuple本身和std::get()应该在最终代码中“消失”,并且不提供运行时开销

也许有更好的方法来解决我的问题…

它应该是等效的,但唯一可以确保的方法是使用您正在使用的编译器进行测试

请注意,您可以将
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
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();
    }
    // ...
这允许用户选择传递什么,而不是强迫他使用自由函数或静态成员函数