Skip to content

Instantly share code, notes, and snippets.

@daniel-j-h
Last active April 20, 2020 13:10
Show Gist options
  • Save daniel-j-h/c4a7788fd560e94db9f7 to your computer and use it in GitHub Desktop.
Save daniel-j-h/c4a7788fd560e94db9f7 to your computer and use it in GitHub Desktop.
expand_pack --- shortcut for parameter pack expansion into swallowing initializer_list
#include <cstdlib>
#include <iostream>
#include <initializer_list>
#define expand_pack(...) (void) std::initializer_list<int>{((void)(__VA_ARGS__), 0)...};
template <typename... Iter>
void increment_all(Iter&... iters) {
expand_pack(++iters);
}
template <typename... Ts>
void print_all(const Ts&... ts) {
expand_pack(std::cout << ts << ' ');
}
template <typename... Ts>
std::size_t size_all(const Ts&... ts) {
std::size_t sizes{0};
expand_pack(sizes += ts.size());
return sizes;
}
int main() {
int a{0}, b{1}, c{2};
increment_all(a, b, c);
print_all(a, b, c);
}
@daniel-j-h
Copy link
Author

#define expand_pack(...) (void) std::initializer_list<int>{((void)(__VA_ARGS__), 0)...};
                   (1)                       (2)                        (3)

(1) variadic macro to take an arbitrary number of arguments ... (the expression on the parameter pack to expand): enables us to not having to parenthesize expressions that have a comma on the call site; these arguments can be expanded via __VA_ARGS__ inside the macro's body

(3) (expression)... expands the parameter pack, ((void)(_), 0)... expands the parameter pack using the comma operator, that is evaluating the left hand side and returning the right hand side; because the comma operator could be overloaded we cast the left hand side to void; you can think of this as sequencing the left hand side expressions and expanding to 0, 0, 0, ...

(2) (void) std::initializer_list<int>{_} creates a temporary initializer list which we cast to void to silence unused-variable warnings; we use it's variadic constructor to swallow the 0s from the comma operator's right hand side; the initializer list guarantees left-to-right sequencing which we especially need for expressions that have side-effects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment