CppCon 2015: Vittorio Romeo “`for_each_argument` explained and expanded"
Why Stack Overflow recommends it
Stack Overflow users link it when explaining how to loop over a variadic parameter pack in C++11/14, as the pre-C++17 alternative to fold expressions.
Recommended by 1 people across 5 different months, 2016 to 2018.
What it is
A CppCon 2015 talk by Vittorio Romeo on Sean Parent's for_each_argument snippet, which iterates at compile time over a function's variadic arguments and forwards each one to a callable. He builds it up step by step with independently compiled code segments, then generalises it and shows use cases.
What people said
Recommends Vittorio Romeo · 2017-01 · Stack Overflow · on “C++ expand variadic template arguments into a statement”
C++17 solution - fold expression [LINK] : template <typename... Ts> auto anyCondition(Ts... xs) { return (xs || ...); } wandbox example [LINK] C++11 solution - for_each_argument : template <typename TF, typename... Ts> void for_each_argument(TF&& f, Ts&&... xs) { (void)(int[]){(f(std::forward<Ts>(xs)), 0)...}; } template <typename... Ts> auto anyCondition(Ts... xs) { bool acc = false; for_each_argument([&acc](bool x){ acc = acc || x; }, xs...); return acc; } wandbox example [LINK] I gave a talk about this snippet at CppCon 2015: CppCon 2015: Vittorio Romeo “for_each_argument explained and expanded" [this video]
Recommends Vittorio Romeo · 2017-03 · Stack Overflow · on “Using fold expressions to print all variadic arguments with newlines inbetween”
This is a *fold expression* over the comma operator. C++11 allows a similar technique (`for_each_argument`) by (ab)using contexts where an expansion can take place. I gave a talk about that at CppCon 2015 [this video] that explains how it works.
Recommends Vittorio Romeo · 2017-03 · Stack Overflow · on “iterate in variadic templates without parameters”
@Morgan: it's commonly known as the `for_each_argument` snippet by Sean Parent. I made a 30 minutes talk about it at CppCon 2015: **“`for_each_argument` explained and expanded"** [this video]
Recommends Vittorio Romeo · 2017-07 · Stack Overflow · on “C++ Concatenate containers of polymorphic objects”
There's no need for polymorphism in your current situation. You could simply use a variadic template + higher-order function to iterate over the vectors. Here's a C++17 solution using a fold expression : template <typename F, typename... Vectors> void for_all_vectors(F&& f, Vectors&&... vs) { (std::for_each(std::forward<Vectors>(vs).begin(), std::forward<Vectors>(vs).end(), f), ...); } Usage: int main() { std::vector<A> my_a; std::vector<B> my_b; std::vector<C> my_c; for_all_vectors([](const auto& x){ something(x); }, my_a, my_b, my_c); } live example on wandbox [LINK] In C++11/14 you can replace the fold expression with for_each_argument : template <typename TF, typename... Ts> void for_eac
Recommends Vittorio Romeo · 2017-09 · Stack Overflow · on “Is there any way to make 'std::cin' in C++ into a 'scan()' function?”
@geza: yes, you can use the `for_each_argument` trick with `initializer_list` [this video] , or use variadic template recursion.
Recommends Vittorio Romeo · 2018-07 · Stack Overflow · on “Loop a list of typedefs”
Sadly, this is harder to do in C++11. You need to replace the *fold expression* with an `initializer_list` (see my talk on the subject [this video] ) and the generic lambda with a `struct` having a templated `operator()`. The usage syntax will not be as nice. It definitely is possible without recursion, though.
Cites 5gon12eder · 2016-01 · Stack Overflow · on “Fallback to to_string() when operator<<() fails”
Yes, it is possible. #include <iostream> #include <sstream> #include <string> #include <type_traits> struct streamy { }; std::ostream& operator<<(std::ostream& os, const streamy& obj) { return os << "streamy [" << static_cast<const void *>(&obj) << "]"; } struct stringy { }; std::string to_string(const stringy& obj) { auto oss = std::ostringstream {}; oss << "stringy [" << static_cast<const void *>(&obj) << "]"; return oss.str(); } template <typename T> std::enable_if_t < std::is_same < std::string, decltype(to_string(std::declval<const T&>())) >::value, std::ostream >& operator<<(std::ostream& os, const T& obj) { return os << to_string(obj); } int main() { std::cout << streamy {} << '\n'; s
Cites Vittorio Romeo · 2016-04 · Stack Overflow · on “How do you static_assert the values in a parameter pack of a variadic template?”
You cannot use a traditional for loop with compile-time values, but there are many ways you can iterate over a compile-time collection. In your case, however, it is not necessary to explicitly loop over every single number: you can use pack expansion to make sure the numbers are only 0 or 1 : coliru example [LINK] #include <type_traits> // We define a `conjunction<...>` helper that will evaluate to // a true boolean `std::integral_constant` if all passed types evaluate // to true. template <typename...> struct conjunction : std::true_type { }; template <typename T> struct conjunction<T> : T { }; template <typename T, typename... Ts> struct conjunction<T, Ts...> : std::conditional_t<T::value
Cites Vittorio Romeo · 2017-12 · Stack Overflow · on “Avoid if-else branching in string to type dispatching”
You don't need to use the preprocessor to store an arbitrary list of types and generate code for them. We can use variadic templates and compile-time strings . You can isolate preprocessor usage to the generation of pairs of names and types. Firstly, let's define a wrapper for a compile-time sequence of characters. Note that the use of the _cs literal is non-Standard, but available in every major compiler and likely to be part of C++20: template <char... Cs> using ct_str = std::integer_sequence<char, Cs...>; template <typename T, T... Cs> constexpr ct_str<Cs...> operator""_cs() { return {}; } We can then define an empty type that stores a pair of a name and a type: template <typename Name, t
Cites Vittorio Romeo · 2017-12 · Stack Overflow · on “Check if all std::tuple elements meet a condition + design concerns”
You could use std::apply [LINK] to unpack the tuple more easily: template <typename F, typename Tuple> constexpr bool tuple_all_of(F&& fn, const Tuple& t) { return std::apply([&fn](const auto&... xs) { return (fn(xs) && ...); }, t); } The fold expression can be replaced with for_each_argument [this video] : template <typename F, typename Tuple> constexpr bool tuple_all_of(F&& fn, const Tuple& t) { bool result = true; std::apply([&](const auto&... xs) { for_each_argument([&](const auto& x) { if(fn(x)) result = false; }, xs...); }, t); return result; } template <class F, class... Ts> void for_each_argument(F f, Ts&&... a) { (void)std::initializer_list<int>{(f(std::forward<Ts>(a)), 0)...}; }