Вопрос

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?

Это было полезно?

Решение

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, ...)

Другие советы

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...});
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top