考虑带有可变模板参数的模板函数的情况:template<typename Tret, typename... T> Tret func(const T&... t);现在,我有一个元组t价值观念。我怎么打电话func()使用元组值作为参数?我读过bind()函数对象call()函数,以及apply()功能在不同的一些现已过时的文件中。GNU GCC 4.4的实现似乎有一个call()函数中的bind()类,但是关于这个主题的文档很少。有些人建议手工编写递归Hack,但各种模板参数的真正价值是能够在上述情况下使用它们。有没有人对IS有一个解决方案,或者暗示在哪里读到它?如何将元组扩展为可变模板函数的参数?
3 回答
梵蒂冈之花
TA贡献1900条经验 获得超5个赞
#include <tr1/tuple>/** * Object Function Tuple Argument Unpacking * * This recursive template unpacks the tuple parameters into * variadic template arguments until we reach the count of 0 where the function * is called with the correct parameters * * @tparam N Number of tuple arguments to unroll * * @ingroup g_util_tuple */template < uint N >struct apply_obj_func{ template < typename T, typename... ArgsF, typename... ArgsT, typename... Args > static void applyTuple( T* pObj, void (T::*f)( ArgsF... ), const std::tr1::tuple<ArgsT...>& t, Args... args ) { apply_obj_func<N-1>::applyTuple( pObj, f, t, std::tr1::get<N-1>( t ), args... ); }};//-----------------------------------------------------------------------------/** * Object Function Tuple Argument Unpacking End Point * * This recursive template unpacks the tuple parameters into * variadic template arguments until we reach the count of 0 where the function * is called with the correct parameters * * @ingroup g_util_tuple */template <>struct apply_obj_func<0>{ template < typename T, typename... ArgsF, typename... ArgsT, typename... Args > static void applyTuple( T* pObj, void (T::*f)( ArgsF... ), const std::tr1::tuple<ArgsT...>& /* t */, Args... args ) { (pObj->*f)( args... ); }};//-----------------------------------------------------------------------------/** * Object Function Call Forwarding Using Tuple Pack Parameters */// Actual apply functiontemplate < typename T, typename... ArgsF, typename... ArgsT >void applyTuple( T* pObj, void (T::*f)( ArgsF... ), std::tr1::tuple<ArgsT...> const& t ){ apply_obj_func<sizeof...(ArgsT)>::applyTuple( pObj, f, t );}//-----------------------------------------------------------------------------/** * Static Function Tuple Argument Unpacking * * This recursive template unpacks the tuple parameters into * variadic template arguments until we reach the count of 0 where the function * is called with the correct parameters * * @tparam N Number of tuple arguments to unroll * * @ingroup g_util_tuple */template < uint N >struct apply_func{ template < typename... ArgsF, typename... ArgsT, typename... Args > static void applyTuple( void (*f)( ArgsF... ), const std::tr1::tuple<ArgsT...>& t, Args... args ) { apply_func<N-1>::applyTuple( f, t, std::tr1::get<N-1>( t ), args... ); }};//-----------------------------------------------------------------------------/** * Static Function Tuple Argument Unpacking End Point * * This recursive template unpacks the tuple parameters into * variadic template arguments until we reach the count of 0 where the function * is called with the correct parameters * * @ingroup g_util_tuple */template <>struct apply_func<0>{ template < typename... ArgsF, typename... ArgsT, typename... Args > static void applyTuple( void (*f)( ArgsF... ), const std::tr1::tuple<ArgsT...>& /* t */, Args... args ) { f( args... ); }};//-----------------------------------------------------------------------------/** * Static Function Call Forwarding Using Tuple Pack Parameters */// Actual apply functiontemplate < typename... ArgsF, typename... ArgsT >void applyTuple( void (*f)(ArgsF...), std::tr1::tuple<ArgsT...> const& t ){ apply_func<sizeof...(ArgsT)>::applyTuple( f, t );}// ***************************************// Usage// ***************************************template < typename T, typename... Args >class Message : public IMessage{ typedef void (T::*F)( Args... args );public: Message( const std::string& name, T& obj, F pFunc, Args... args );private: virtual void doDispatch( ); T* pObj_; F pFunc_; std::tr1::tuple<Args...> args_;};//-----------------------------------------------------------------------------template < typename T, typename... Args >Message<T, Args...>::Message( const std::string& name, T& obj, F pFunc, Args... args ): IMessage( name ), pObj_( &obj ), pFunc_( pFunc ), args_( std::forward<Args>(args)... ){}//-----------------------------------------------------------------------------template < typename T, typename... Args >void Message<T, Args...>::doDispatch( ){ try { applyTuple( pObj_, pFunc_, args_ ); } catch ( std::exception& e ) { }}
HUWWW
TA贡献1874条经验 获得超12个赞
// ------------- UTILITY---------------template<int...> struct index_tuple{}; template<int I, typename IndexTuple, typename... Types> struct make_indexes_impl; template<int I, int... Indexes, typename T, typename ... Types> struct make_indexes_impl<I, index_tuple<Indexes...>, T, Types...> { typedef typename make_indexes_impl<I + 1, index_tuple<Indexes..., I>, Types...>::type type; }; template<int I, int... Indexes> struct make_indexes_impl<I, index_tuple<Indexes...> > { typedef index_tuple<Indexes...> type; }; template<typename ... Types> struct make_indexes : make_indexes_impl<0, index_tuple<>, Types...> {};
// ----------UNPACK TUPLE AND APPLY TO FUNCTION ---------#include <tuple>#include <iostream> using namespace std;template<class Ret, class... Args, int... Indexes > Ret apply_helper( Ret (*pf)(Args...), index_tuple< Indexes... >, tuple<Args...>&& tup) { return pf( forward<Args>( get<Indexes>(tup))... ); } template<class Ret, class ... Args> Ret apply(Ret (*pf)(Args...), const tuple<Args...>& tup){ return apply_helper(pf, typename make_indexes<Args...>::type(), tuple<Args...>(tup));}template<class Ret, class ... Args> Ret apply(Ret (*pf)(Args...), tuple<Args...>&& tup){ return apply_helper(pf, typename make_indexes<Args...>::type(), forward<tuple<Args...>>(tup));}
// --------------------- TEST ------------------void one(int i, double d){ std::cout << "function one(" << i << ", " << d << ");\n";}int two(int i){ std::cout << "function two(" << i << ");\n"; return i;}int main(){ std::tuple<int, double> tup(23, 4.5); apply(one, tup); int d = apply(two, std::make_tuple(2)); return 0;}
- 3 回答
- 0 关注
- 543 浏览
添加回答
举报
0/150
提交
取消