Skip to content

Instantly share code, notes, and snippets.

@nbp
Created July 16, 2015 21:43
Show Gist options
  • Save nbp/5087046ad8c3cedc31fe to your computer and use it in GitHub Desktop.
Save nbp/5087046ad8c3cedc31fe to your computer and use it in GitHub Desktop.
Iterative variadic templates
#define METHOD 1
// I admit this is not an easy function to understand, but you will love it
// in a few seconds.
void reverseForEach(...) { }
#if METHOD == 1
// This method use a separate data structure as an accumulator, and call a
// method to mutate the content of the accumulator. If you don't see any
// use of it, replace "Adder" by "std::vector", and "add" by "push_back".
struct Adder {
int result;
Adder() : result(0) {}
int add(int i) {
result += i;
return 0;
}
};
template <typename... Elems>
int add_args(Elems... elems)
{
Adder a;
reverseForEach(a.add(elems)...);
return a.result;
}
#elif METHOD == 2
// This one is the nicest version, but apparently some versions of GCC don't
// like having the lambda inside. Thus you might have to fallback on the
// method 3. (I have not verified with the latest versions of gcc yet)
template <typename... Elems>
int add_args(Elems... elems)
{
int result;
reverseForEach(([&](int i) -> int {
result += i;
return 0;
})(elems)...);
return result;
}
#elif METHOD == 3
template <typename... Elems>
int add_args(Elems... elems)
{
int result;
auto step = [&](int i) -> int {
result += i;
return 0;
};
reverseForEach(step(elems)...);
return result;
}
#endif
int main()
{
return add_args(1, 2, 3, 4);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment