Templates 使用可变模板索引
假设我有一个正在展开的参数包,例如Templates 使用可变模板索引,templates,c++11,variadic,Templates,C++11,Variadic,假设我有一个正在展开的参数包,例如 template<typename... P> void f(P...&& args) { some_other_func(std::forward<P>(args)...); } 我可以把它扩展到 some_other_func(some_func(arg1, 1), some_func(arg2, 2)); 例如?它有点复杂。但是这里有一个代码的工作原型,它使用了的几个私有实用程序,可以在中找到 ,及 #
template<typename... P> void f(P...&& args) {
some_other_func(std::forward<P>(args)...);
}
我可以把它扩展到
some_other_func(some_func(arg1, 1), some_func(arg2, 2));
例如?它有点复杂。但是这里有一个代码的工作原型,它使用了的几个私有实用程序,可以在中找到 ,及
#包括
#包括
模板
int
一些函数(T&&ref,size\T I)
{
std::cout我知道我以前解决过这个问题,但不记得是怎么解决的。哦,好吧,这是一个全新的视角
可以使用std::get
将数字序列转换为参数序列,因此它更基本。因此,假设我需要实现某种自定义工具,数字包生成器似乎是一个不错的选择
(嘎,这真是令人难以置信的乏味。我确实看了霍华德的答案,并学习了前进作为元组
,但这个函数在我的编译器或ideone.com上还不存在,所以诸如此类。我还有很多事情需要弄清楚,这肯定是有史以来最糟糕的函数语言之一。)
#包括
//通用包数组(元容器)
模板结构值\u序列{
//将值附加到数组(元函数)
模板struct append
{typedef value_sequencetype;};
};
//生成序列数组(元函数)
模板
结构索引\u序列{
typedef typename索引_序列::type
::模板追加::类型;
};
模板
结构索引\u序列<0>
{typedef value_sequencetype;};
//生成最大为给定元组大小的索引(元函数)
模板
结构索引元组{
typedef typename索引_序列::值
>::类型类型;
};
//神奇的函数:传递索引,进行所有函数调用
模板
void compose_与_索引_helper(F,G,T参数,
值\u序列<大小\u t,N…>){
f(g(std::get(args),N)…);
}
模板
void compose_与_索引(F、G、T&…args){
typedef std::tupletuple\T;
使用\u索引\u辅助对象组合\u
//在ideone.com/GCC 4.5.1“解决方案”上,转发似乎已中断。
//(f,g,std::forward_as_tuple(std::forward(args)…);
(f,g,tuple_t(args…),typename index_tuple::type());
}
谢谢。当然不会使用LISSTDC C++私人内部设备。我唯一能想到的是比C++更冗长乏味,而多元模板是C++,没有元组和可变模板。事实上,我会标准化一些有用的实用程序,比如你上面展示的那些,或者我在libc++中利用的那些。然后希望事情不会那么乏味。@Howard:tuple
我喜欢,似乎是参数包接口抵制封装。大笑,甚至不想尝试!:-)
template<typename... P> void f(P...&& args) {
some_other_func(some_func(args)...);
}
some_other_func(some_func(arg1), some_func(arg2));
some_other_func(some_func(arg1, 1), some_func(arg2, 2));
#include <iostream>
#include <tuple>
template<typename T>
int
some_func(T&& ref, size_t I)
{
std::cout << "ref = " << ref << ", I = " << I << '\n';
return 0;
}
template<typename... T, size_t ...Indx>
void
some_other_func(std::tuple<T...> ref, std::__tuple_indices<Indx...>) {
// replace with actual logic
std::__swallow(some_func(std::get<Indx>(ref), Indx)...);
}
template<typename... P>
void
f(P&&... args)
{
some_other_func(std::forward_as_tuple<P...>(std::forward<P>(args)...),
typename std::__make_tuple_indices<sizeof...(P)>::type());
}
int main()
{
f("zero", "one", "two", "three");
}
ref = zero, I = 0
ref = one, I = 1
ref = two, I = 2
ref = three, I = 3
#include <tuple>
// Generic pack array (metacontainer)
template< typename T, T ... seq > struct value_sequence {
// Append a value to the array (metafunction)
template< T val > struct append
{ typedef value_sequence< T, seq..., val > type; };
};
// Generate a sequential array (metafunction)
template< size_t N >
struct index_sequence {
typedef typename index_sequence< N - 1 >::type
::template append< N - 1 >::type type;
};
template<>
struct index_sequence< 0 >
{ typedef value_sequence< size_t > type; };
// Generate indexes up to size of given tuple (metafunction)
template< typename T >
struct index_tuple {
typedef typename index_sequence< std::tuple_size< T >::value
>::type type;
};
// The magic function: passes indexes, makes all the function calls
template< typename F, typename G,
typename T, size_t ... N >
void compose_with_indexes_helper( F f, G g, T args,
value_sequence< size_t, N ... > ) {
f( g( std::get< N >( args ), N ) ... );
}
template< typename F, typename G, typename ... T >
void compose_with_indexes( F f, G g, T && ... args ) {
typedef std::tuple< T && ... > tuple_t;
compose_with_indexes_helper
// forwarding seems broken on ideone.com/GCC 4.5.1, work around.
// ( f, g, std::forward_as_tuple( std::forward( args ) ... ) );
( f, g, tuple_t( args ... ), typename index_tuple< tuple_t >::type() );
}