如何将元组扩展为可变模板函数的参数?

考虑带有可变模板参数的模板函数的情况:

template<typename Tret, typename... T> Tret func(const T&... t);

现在,我有一个元组t价值观念。我怎么打电话func()使用元组值作为参数?我读过bind()函数对象call()函数,以及apply()功能在不同的一些现已过时的文件中。GNU GCC 4.4的实现似乎有一个call()函数中的bind()类,但是关于这个主题的文档很少。

有些人建议手工编写递归Hack,但各种模板参数的真正价值是能够在上述情况下使用它们。

有没有人对IS有一个解决方案,或者暗示在哪里读到它?

如何将元组扩展为可变模板函数的参数?

守着星空守着你
浏览 544回答 3
3回答

梵蒂冈之花

这是我的代码,如果有人感兴趣的话基本上,在编译时,编译器将递归地展开各种包含函数调用<N>->调用<N-1>->调用的所有参数.->调用<0>这是最后一个调用,编译器将优化各种中间函数调用,只保留与func等效的最后一个函数(arg1、arg 2、arg3、.)提供了两个版本,一个用于调用对象上的函数,另一个用于静态函数。#include&nbsp;<tr1/tuple>/** &nbsp;*&nbsp;Object&nbsp;Function&nbsp;Tuple&nbsp;Argument&nbsp;Unpacking &nbsp;* &nbsp;*&nbsp;This&nbsp;recursive&nbsp;template&nbsp;unpacks&nbsp;the&nbsp;tuple&nbsp;parameters&nbsp;into &nbsp;*&nbsp;variadic&nbsp;template&nbsp;arguments&nbsp;until&nbsp;we&nbsp;reach&nbsp;the&nbsp;count&nbsp;of&nbsp;0&nbsp;where&nbsp;the&nbsp;function &nbsp;*&nbsp;is&nbsp;called&nbsp;with&nbsp;the&nbsp;correct&nbsp;parameters &nbsp;* &nbsp;*&nbsp;@tparam&nbsp;N&nbsp;Number&nbsp;of&nbsp;tuple&nbsp;arguments&nbsp;to&nbsp;unroll &nbsp;* &nbsp;*&nbsp;@ingroup&nbsp;g_util_tuple &nbsp;*/template&nbsp;<&nbsp;uint&nbsp;N&nbsp;>struct&nbsp;apply_obj_func{ &nbsp;&nbsp;template&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT,&nbsp;typename...&nbsp;Args&nbsp;> &nbsp;&nbsp;static&nbsp;void&nbsp;applyTuple(&nbsp;T*&nbsp;pObj, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;(T::*f)(&nbsp;ArgsF...&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;std::tr1::tuple<ArgsT...>&&nbsp;t, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;apply_obj_func<N-1>::applyTuple(&nbsp;pObj,&nbsp;f,&nbsp;t,&nbsp;std::tr1::get<N-1>(&nbsp;t&nbsp;),&nbsp;args...&nbsp;); &nbsp;&nbsp;}};//-----------------------------------------------------------------------------/** &nbsp;*&nbsp;Object&nbsp;Function&nbsp;Tuple&nbsp;Argument&nbsp;Unpacking&nbsp;End&nbsp;Point &nbsp;* &nbsp;*&nbsp;This&nbsp;recursive&nbsp;template&nbsp;unpacks&nbsp;the&nbsp;tuple&nbsp;parameters&nbsp;into &nbsp;*&nbsp;variadic&nbsp;template&nbsp;arguments&nbsp;until&nbsp;we&nbsp;reach&nbsp;the&nbsp;count&nbsp;of&nbsp;0&nbsp;where&nbsp;the&nbsp;function &nbsp;*&nbsp;is&nbsp;called&nbsp;with&nbsp;the&nbsp;correct&nbsp;parameters &nbsp;* &nbsp;*&nbsp;@ingroup&nbsp;g_util_tuple &nbsp;*/template&nbsp;<>struct&nbsp;apply_obj_func<0>{ &nbsp;&nbsp;template&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT,&nbsp;typename...&nbsp;Args&nbsp;> &nbsp;&nbsp;static&nbsp;void&nbsp;applyTuple(&nbsp;T*&nbsp;pObj, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;(T::*f)(&nbsp;ArgsF...&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;std::tr1::tuple<ArgsT...>&&nbsp;/*&nbsp;t&nbsp;*/, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;(pObj->*f)(&nbsp;args...&nbsp;); &nbsp;&nbsp;}};//-----------------------------------------------------------------------------/** &nbsp;*&nbsp;Object&nbsp;Function&nbsp;Call&nbsp;Forwarding&nbsp;Using&nbsp;Tuple&nbsp;Pack&nbsp;Parameters &nbsp;*///&nbsp;Actual&nbsp;apply&nbsp;functiontemplate&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT&nbsp;>void&nbsp;applyTuple(&nbsp;T*&nbsp;pObj, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;(T::*f)(&nbsp;ArgsF...&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::tr1::tuple<ArgsT...>&nbsp;const&&nbsp;t&nbsp;){ &nbsp;&nbsp;&nbsp;apply_obj_func<sizeof...(ArgsT)>::applyTuple(&nbsp;pObj,&nbsp;f,&nbsp;t&nbsp;);}//-----------------------------------------------------------------------------/** &nbsp;*&nbsp;Static&nbsp;Function&nbsp;Tuple&nbsp;Argument&nbsp;Unpacking &nbsp;* &nbsp;*&nbsp;This&nbsp;recursive&nbsp;template&nbsp;unpacks&nbsp;the&nbsp;tuple&nbsp;parameters&nbsp;into &nbsp;*&nbsp;variadic&nbsp;template&nbsp;arguments&nbsp;until&nbsp;we&nbsp;reach&nbsp;the&nbsp;count&nbsp;of&nbsp;0&nbsp;where&nbsp;the&nbsp;function &nbsp;*&nbsp;is&nbsp;called&nbsp;with&nbsp;the&nbsp;correct&nbsp;parameters &nbsp;* &nbsp;*&nbsp;@tparam&nbsp;N&nbsp;Number&nbsp;of&nbsp;tuple&nbsp;arguments&nbsp;to&nbsp;unroll &nbsp;* &nbsp;*&nbsp;@ingroup&nbsp;g_util_tuple &nbsp;*/template&nbsp;<&nbsp;uint&nbsp;N&nbsp;>struct&nbsp;apply_func{ &nbsp;&nbsp;template&nbsp;<&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT,&nbsp;typename...&nbsp;Args&nbsp;> &nbsp;&nbsp;static&nbsp;void&nbsp;applyTuple(&nbsp;void&nbsp;(*f)(&nbsp;ArgsF...&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;std::tr1::tuple<ArgsT...>&&nbsp;t, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;apply_func<N-1>::applyTuple(&nbsp;f,&nbsp;t,&nbsp;std::tr1::get<N-1>(&nbsp;t&nbsp;),&nbsp;args...&nbsp;); &nbsp;&nbsp;}};//-----------------------------------------------------------------------------/** &nbsp;*&nbsp;Static&nbsp;Function&nbsp;Tuple&nbsp;Argument&nbsp;Unpacking&nbsp;End&nbsp;Point &nbsp;* &nbsp;*&nbsp;This&nbsp;recursive&nbsp;template&nbsp;unpacks&nbsp;the&nbsp;tuple&nbsp;parameters&nbsp;into &nbsp;*&nbsp;variadic&nbsp;template&nbsp;arguments&nbsp;until&nbsp;we&nbsp;reach&nbsp;the&nbsp;count&nbsp;of&nbsp;0&nbsp;where&nbsp;the&nbsp;function &nbsp;*&nbsp;is&nbsp;called&nbsp;with&nbsp;the&nbsp;correct&nbsp;parameters &nbsp;* &nbsp;*&nbsp;@ingroup&nbsp;g_util_tuple &nbsp;*/template&nbsp;<>struct&nbsp;apply_func<0>{ &nbsp;&nbsp;template&nbsp;<&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT,&nbsp;typename...&nbsp;Args&nbsp;> &nbsp;&nbsp;static&nbsp;void&nbsp;applyTuple(&nbsp;void&nbsp;(*f)(&nbsp;ArgsF...&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;std::tr1::tuple<ArgsT...>&&nbsp;/*&nbsp;t&nbsp;*/, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;f(&nbsp;args...&nbsp;); &nbsp;&nbsp;}};//-----------------------------------------------------------------------------/** &nbsp;*&nbsp;Static&nbsp;Function&nbsp;Call&nbsp;Forwarding&nbsp;Using&nbsp;Tuple&nbsp;Pack&nbsp;Parameters &nbsp;*///&nbsp;Actual&nbsp;apply&nbsp;functiontemplate&nbsp;<&nbsp;typename...&nbsp;ArgsF,&nbsp;typename...&nbsp;ArgsT&nbsp;>void&nbsp;applyTuple(&nbsp;void&nbsp;(*f)(ArgsF...), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::tr1::tuple<ArgsT...>&nbsp;const&&nbsp;t&nbsp;){ &nbsp;&nbsp;&nbsp;apply_func<sizeof...(ArgsT)>::applyTuple(&nbsp;f,&nbsp;t&nbsp;);}//&nbsp;***************************************//&nbsp;Usage//&nbsp;***************************************template&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;Args&nbsp;>class&nbsp;Message&nbsp;:&nbsp;public&nbsp;IMessage{ &nbsp;&nbsp;typedef&nbsp;void&nbsp;(T::*F)(&nbsp;Args...&nbsp;args&nbsp;);public: &nbsp;&nbsp;Message(&nbsp;const&nbsp;std::string&&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&&nbsp;obj, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F&nbsp;pFunc, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;);private: &nbsp;&nbsp;virtual&nbsp;void&nbsp;doDispatch(&nbsp;); &nbsp;&nbsp;T*&nbsp;&nbsp;pObj_; &nbsp;&nbsp;F&nbsp;&nbsp;&nbsp;pFunc_; &nbsp;&nbsp;std::tr1::tuple<Args...>&nbsp;args_;};//-----------------------------------------------------------------------------template&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;Args&nbsp;>Message<T,&nbsp;Args...>::Message(&nbsp;const&nbsp;std::string&&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&&nbsp;obj, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F&nbsp;pFunc, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Args...&nbsp;args&nbsp;):&nbsp;IMessage(&nbsp;name&nbsp;), &nbsp;&nbsp;pObj_(&nbsp;&obj&nbsp;), &nbsp;&nbsp;pFunc_(&nbsp;pFunc&nbsp;), &nbsp;&nbsp;args_(&nbsp;std::forward<Args>(args)...&nbsp;){}//-----------------------------------------------------------------------------template&nbsp;<&nbsp;typename&nbsp;T,&nbsp;typename...&nbsp;Args&nbsp;>void&nbsp;Message<T,&nbsp;Args...>::doDispatch(&nbsp;){ &nbsp;&nbsp;try &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;applyTuple(&nbsp;pObj_,&nbsp;pFunc_,&nbsp;args_&nbsp;); &nbsp;&nbsp;} &nbsp;&nbsp;catch&nbsp;(&nbsp;std::exception&&nbsp;e&nbsp;) &nbsp;&nbsp;{ &nbsp;&nbsp;}}

HUWWW

在C+中,有许多方法可以扩展/解压缩元组,并将这些元组元素应用到可变模板函数中。下面是一个创建索引数组的小助手类。它在模板元编程中经常使用://&nbsp;-------------&nbsp;UTILITY---------------template<int...>&nbsp;struct&nbsp;index_tuple{};&nbsp;template<int&nbsp;I,&nbsp;typename&nbsp;IndexTuple,&nbsp;typename...&nbsp;Types>&nbsp;struct&nbsp;make_indexes_impl;&nbsp;template<int&nbsp;I,&nbsp;int...&nbsp;Indexes,&nbsp;typename&nbsp;T,&nbsp;typename&nbsp;...&nbsp;Types>&nbsp;struct&nbsp;make_indexes_impl<I,&nbsp;index_tuple<Indexes...>,&nbsp;T,&nbsp;Types...>&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;make_indexes_impl<I&nbsp;+&nbsp;1,&nbsp;index_tuple<Indexes...,&nbsp;I>,&nbsp;Types...>::type&nbsp;type;&nbsp;};&nbsp;template<int&nbsp;I,&nbsp;int...&nbsp;Indexes>&nbsp;struct&nbsp;make_indexes_impl<I,&nbsp;index_tuple<Indexes...>&nbsp;>&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;index_tuple<Indexes...>&nbsp;type;&nbsp;};&nbsp;template<typename&nbsp;...&nbsp;Types>&nbsp;struct&nbsp;make_indexes&nbsp;:&nbsp;make_indexes_impl<0,&nbsp;index_tuple<>,&nbsp;Types...>&nbsp;{};现在,完成这项工作的代码并没有那么大:&nbsp;//&nbsp;----------UNPACK&nbsp;TUPLE&nbsp;AND&nbsp;APPLY&nbsp;TO&nbsp;FUNCTION&nbsp;---------#include&nbsp;<tuple>#include&nbsp;<iostream>&nbsp;using&nbsp;namespace&nbsp;std;template<class&nbsp;Ret,&nbsp;class...&nbsp;Args,&nbsp;int...&nbsp;Indexes&nbsp;>&nbsp;Ret&nbsp;apply_helper(&nbsp;Ret&nbsp;(*pf)(Args...),&nbsp;index_tuple<&nbsp;Indexes...&nbsp;>,&nbsp;tuple<Args...>&&&nbsp;tup)&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;pf(&nbsp;forward<Args>(&nbsp;get<Indexes>(tup))...&nbsp;);&nbsp;}&nbsp;template<class&nbsp;Ret,&nbsp;class&nbsp;...&nbsp;Args>&nbsp;Ret&nbsp;apply(Ret&nbsp;(*pf)(Args...),&nbsp;const&nbsp;tuple<Args...>&&nbsp;&nbsp;tup){ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;apply_helper(pf,&nbsp;typename&nbsp;make_indexes<Args...>::type(),&nbsp;tuple<Args...>(tup));}template<class&nbsp;Ret,&nbsp;class&nbsp;...&nbsp;Args>&nbsp;Ret&nbsp;apply(Ret&nbsp;(*pf)(Args...),&nbsp;tuple<Args...>&&&nbsp;&nbsp;tup){ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;apply_helper(pf,&nbsp;typename&nbsp;make_indexes<Args...>::type(),&nbsp;forward<tuple<Args...>>(tup));}试验如下://&nbsp;---------------------&nbsp;TEST&nbsp;------------------void&nbsp;one(int&nbsp;i,&nbsp;double&nbsp;d){ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"function&nbsp;one("&nbsp;<<&nbsp;i&nbsp;<<&nbsp;",&nbsp;"&nbsp;<<&nbsp;d&nbsp;<<&nbsp;");\n";}int&nbsp;two(int&nbsp;i){ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"function&nbsp;two("&nbsp;<<&nbsp;i&nbsp;<<&nbsp;");\n"; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;i;}int&nbsp;main(){ &nbsp;&nbsp;&nbsp;&nbsp;std::tuple<int,&nbsp;double>&nbsp;tup(23,&nbsp;4.5); &nbsp;&nbsp;&nbsp;&nbsp;apply(one,&nbsp;tup); &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;d&nbsp;=&nbsp;apply(two,&nbsp;std::make_tuple(2));&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}我不是其他语言的专家,但我想如果这些语言在菜单中没有这样的功能,就没有办法做到这一点。至少用C+你可以,而且我认为这不是很复杂.
打开App,查看更多内容
随时随地看视频慕课网APP