C++11 在0中拆分参数包。。。N-1和N元素

C++11 在0中拆分参数包。。。N-1和N元素,c++11,variadic-templates,C++11,Variadic Templates,我想把一个参数包分为第一个N-1和第N个参数,而不使用典型的索引序列和元组技巧,但我似乎无法理解它,但我很确定它应该是可行的?(使用递归获取最后一项非常简单) 要调用的最后一个函数如下所示 void Fun( Foo a, Bar b ); 并且,依次从可变值中获取a: template< class... T > Foo CalcFoo( T... args ); 模板 Foo-CalcFoo(T…args); 我目前的执行情况: //get the last item of

我想把一个参数包分为第一个N-1和第N个参数,而不使用典型的索引序列和元组技巧,但我似乎无法理解它,但我很确定它应该是可行的?(使用递归获取最后一项非常简单)

要调用的最后一个函数如下所示

void Fun( Foo a, Bar b );
并且,依次从可变值中获取a:

template< class... T >
Foo CalcFoo( T... args );
模板
Foo-CalcFoo(T…args);
我目前的执行情况:

//get the last item of the pack
template< class T >
T split_last( T t ){ return t; }

template< class... T >
T split_last( T, T... t ){ return split_last( t... ); }

//helper
template< class... T, size_t... Indices >
Foo CalcFoo( const std::tuple< T... >& args, index_sequence< Indices... > )
{
  return CalcFoo( std::get< Indices >( args )... );
}

//split and call
template< class... T >
void MoreFun( T... args )
{
  //make a tuple containing all, then get n -1 items out of it
  const auto tup = std::make_tuple< T... >( args... );
  Fun( CalcFoo( tup, make_index_sequence< sizeof...( T ) - 1 >() ),
       split_last( args... ) ); 
}
//获取包的最后一项
模板
T拆分_last(T){返回T;}
模板<类。。。T>
T split_last(T,T…T){返回split_last(T…);}
//助手
模板<类。。。T、 大小\u T。。。指数>
Foo-CalcFoo(const-std::tuple&args,index_-sequence)
{
返回CalcFoo(std::get(args)…);
}
//拆分并调用
模板<类。。。T>
void MoreFun(T…args)
{
//制作一个包含all的元组,然后从中获取n-1项
const auto tup=std::make_tuple(args…);
乐趣(CalcFoo(tup,make_index_sequence()),
最后拆分(args…);
}

更新除了想知道如何在没有元组的情况下做到这一点,我还问了这个问题,因为我不知怎的认为元组可能会导致开销。因此忽略了早熟的优化咒语,这和往常一样,再次证明是正确的。使用VS2013在发布模式下编译,my和Horstling的代码产生完全相同的汇编代码。在调用
Fun
之前,包括
CalcFoo
在内的所有内容都是内联的。换句话说:元组完全消失了。所以我可能会坚持使用这个实现,因为它非常清晰。

好吧,让我们发挥创意。我确信有一种更“标准”的方法可以做到这一点,但我有点喜欢这种解决方案;)

核心思想是递归地旋转参数,直到我们可以拆分出(以前的)最后一个参数

template <size_t N>
struct MoreFunHelper
{
    template <class Head, class... Tail>
    static void RotateLeft(Head head, Tail... tail)
    {
        MoreFunHelper<N - 1>::RotateLeft(tail..., head);
    }
};

template <>
struct MoreFunHelper<0>
{
    template <class Head, class... Tail>
    static void RotateLeft(Head head, Tail... tail)
    {
        Fun(CalcFoo(tail...), head);
    }
};

template< class... T >
void MoreFun(T... args)
{
    MoreFunHelper<sizeof...(T) - 1>::RotateLeft(args...);
}
它将它们旋转4次:

2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
现在我们可以将它们平滑地分成[5]和[1 2 3 4],这正是我们想要的。此时,递归停止,只调用函数
CalcFoo
Fun

2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4