Question

Consider I have a variadic template with int... parameters. For example a function like this:

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

All the method should do is adding all the parameters. It can be easily achieved using recursive variadic templates. However, is it also possible expressing this (or something similar like using other binary operators to aggregate all the template parameters) using parameter pack expansion?

Was it helpful?

Solution

Yes, using a trick I learnt from @Xeo in the Lounge. I originally used it to make a variadic "print" template function.

#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';
}

This works on every compiler that has decent C++11 support (GCC 4.8+, Clang 3.2+, MSVS2013, ...)

OTHER TIPS

One possible variant which uses lambda and 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...});
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top