Last active
December 15, 2015 16:39
-
-
Save Redchards/ac14ba4b957f5b8cc774 to your computer and use it in GitHub Desktop.
Apply a function to each arguments abusing C++17 upcoming fold expressions and operator coma (compiling with Clang 3.6 and above)
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
| #include <initializer_list> | |
| // The original version, by Eric Niebler and Sean Parent. Abusing brace initialization to make a liste expansion. | |
| // Would work with any variadic initializable construct, such as array types (T[]) | |
| template<class Fn, class ... Args> | |
| constexpr Fn for_each_args(Fn f, Args&& ... args) | |
| { | |
| using expander = std::initializer_list<int>; | |
| return ((void)expander{(f(args), 0)...}, f); | |
| } | |
| // Here is the version I came up with using fold expressions. In fact, this is the same principle, but you do | |
| // no longer need to abuse a variadic initializable type to achieve the same effect. Same code generation also. | |
| template<class Fn, class ... Args> | |
| constexpr Fn for_each_args(Fn f, Args&& ... args) | |
| { | |
| return ((..., f(std::forward<Args>(args))), f); | |
| } | |
| // Sample usage : | |
| class Ostreamer | |
| { | |
| public: | |
| template<class T> | |
| void operator()(T x) | |
| { | |
| std::cout << x << std::endl; | |
| } | |
| }; | |
| class BasicStreamable | |
| {}; | |
| std::ostream& operator<<(std::ostream& os, BasicStreamable) | |
| { | |
| os << "I'm a streamable !\n"; | |
| return os; | |
| } | |
| for_each_args(Ostreamer{}, 1, 9, 18, 5, "Hello", " World !", BasicStreamable{}); | |
| // Or, if your compiler supports generic lambda functions, you can get read of the "Ostreamer" proxy | |
| for_each_args([](auto x) { | |
| std::cout << x << std::endl; | |
| }, 1, 9, 18, 5, "Hello", " World !", BasicStreamable{}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment