Skip to content

Instantly share code, notes, and snippets.

@SergNikitin
Last active October 1, 2016 16:16
Show Gist options
  • Save SergNikitin/e4feba03b2328a148f89d6703a8cbdb9 to your computer and use it in GitHub Desktop.
Save SergNikitin/e4feba03b2328a148f89d6703a8cbdb9 to your computer and use it in GitHub Desktop.
/**
* @brief Calls a callable for each passed parameter
* @details If callable is a C++14 generic lambda (i.e. [](auto&& arg){};),
* input parameters may be of different types
*/
template <typename Callable, typename... Args>
constexpr void InvokeForEach(const Callable& callable, Args&&... args)
{
// The following approach relies on the fact that contents
// of the array initializer list are evaluated from left to write
// (which is guaranteed by the C++ standard), so the callable is
// invoked for each argument in the same order in which the arguments
// were passed into this function.
// The more conventional way of doing things in variadic functions
// would be making a solution via variadic recursion, but
// there seems to be a consensus that it will produce a more bloated
// code because of recursive calls that may not be optimized away
using ExpandAsArrayInitList = int[];
ExpandAsArrayInitList{
0, // NOTE: forces initializer list to be non-empty
(callable(std::forward<decltype(args)>(args)), // NOTE: comma operator at the end
void(), // NOTE: protects from accidental usage of overloaded comma operator
// since comma operator can't be overloaded for void
0 // NOTE: dummy value that is actually put into the array initializer
// list
)... // NOTE: variadic parameter pack expansion
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment