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() );
}