c++11 - 将参数包拆分为 0 ... N-1 和第 N 个元素

标签 c++11 variadic-templates

我想在不使用典型的 index_sequence & tuple 技巧的情况下将参数包拆分为第一个 N - 1 和第 N 个参数,但似乎无法解决它,但我很确定它应该可行吗? (通过递归获得最后一项很容易)。

要调用的最终函数看起来像

void Fun( Foo a, Bar b );

并且 a 依次从可变参数中获得:
template< class... T >
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... ) ); 
}

更新 除了想知道如何在没有元组的情况下做到这一点,我还问了这个问题,因为我以某种方式认为元组可能会导致开销。从而忽略了过早的优化咒语,像往常一样,它再次被证明是正确的。使用 VS2013 在 Release模式下编译 my 和 HorSTLing 的代码产生完全相同的汇编代码。一切包括 CalcFoo内联直到调用 Fun .换句话说:元组完全消失了。所以无论如何我可能会坚持这个实现,因为它很清楚。

最佳答案

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

http://coliru.stacked-crooked.com/a/25a3fa276e56cd94

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

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

所以如果我们从论点开始
1 2 3 4 5

它将它们旋转 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],这正是我们想要的。此时,递归停止,只调用函数CalcFooFun .

关于c++11 - 将参数包拆分为 0 ... N-1 和第 N 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25685810/

相关文章:

c++ - libc++ 与 VC++ : Can non-UTF conversions be done with wstring_convert?

c++ - C++11 的绑定(bind)函数可以用在 std(或者更好的 mtl) vector 中吗?

c++ - 我需要一个参数数量可变的模板函数

c++ - 多个可变参数模板函数

c++ - 模板参数包扩展语法的基本原理

c++ - 这个创建元组的习语有名字吗?

c++ - 如何在main之前强制初始化静态局部变量?

c++ - 作为拷贝传递的 std::move() 变量有什么影响?

c++ - 符号 T&&..(2 点)是什么意思?

c++ - 如何将 mpl::set 的内容扩展为函数模板的模板参数