Created
July 16, 2015 21:43
-
-
Save nbp/5087046ad8c3cedc31fe to your computer and use it in GitHub Desktop.
Iterative variadic templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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