Last active
October 1, 2016 16:16
-
-
Save SergNikitin/e4feba03b2328a148f89d6703a8cbdb9 to your computer and use it in GitHub Desktop.
This file contains 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
/** | |
* @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