使用参数包扩展添加所有参数

时间:2014-05-13 10:34:44

标签: c++ templates c++11 variadic-templates

考虑我有一个带有int...参数的可变参数模板。例如,像这样的函数:

template<int... t>
int add(){
    return t... + ???
}

所有方法应该做的是添加所有参数。使用递归可变参数模板可以轻松实现。但是,是否也可以使用参数包扩展来表达这种(或类似使用其他二元运算符聚合所有模板参数的东西)?

2 个答案:

答案 0 :(得分:18)

是的,使用我在休息室从@Xeo学到的技巧。我最初用它来制作一个可变的&#34; print&#34;模板功能。

#include <iostream>

template<int... ints>
int add()
{
  int result = 0;
  using expand_variadic_pack  = int[]; // dirty trick, see below
  (void)expand_variadic_pack{0, ((result += ints), void(), 0)... };
  // first void: silence variable unused warning
  // uses braced-init-list initialization rules, which evaluates
  //  the elements inside a braced-init-list IN ORDER, to repetetively
  //  execute a certain operation
  // second void is to prevent malicious "operator," overloads, which
  //  cannot exist for void types
  // 0 at the end is to handle empty variadic pack (zero-size array initializer is illegal.
  return result;
}

int main()
{
  std::cout << add<1,2,3,4>() << '\n';
}

这适用于每个支持C ++ 11的编译器(GCC 4.8 +,Clang 3.2 +,MSVS2013,......)

答案 1 :(得分:7)

一种可能的变体,它使用lambda和std::accumulate

#include <array>
#include <numeric>

template <int... t>
int add()
{
    return [](const std::array<int, sizeof...(t)>& a)
    {
        return std::accumulate(a.begin(), a.end(), 0);
    }({t...});
}