Is there and existing function (or syntax) like:
inline void noop(...) { /* EMPTY */ }
so I can do things like:
template <class... T>
void foo(T... args) {
noop( do_side_effect<T>(args)... );
}
------------- edit -----------
because something like this can not be compiled:
template <class... T>
void foo(T... args) {
do_side_effect<T>(args)...;
}
template <class... T>
void foo(T... args) {
( do_side_effect<T>(args)... );
}
------------ edit 2 -----------
An example to show a possible use case.
template <class T, class F, int... indices>
void _tuple_foreach_details(T&& tuple, F& functor, std::index_sequence<indices...>){
noop( functor(std::get<indices>(tuple))... );
/* this means:
functor(std::get<0>(tuple));
functor(std::get<1>(tuple));
...
functor(std::get<N>(tuple));
*/
}
template <class T, class F>
void tuple_foreach(T&& tuple, F& functor) {
_tuple_foreach_details<T, F, std::make_index_sequence<std::tuple_size_v<T>>>(tuple, functor, {});
}
No, there's no such standard function. We'd need to ensure no expression coming out of the pack has a void
type. And since the evaluation of function arguments is indeterminately sequenced with respect to each other, the use case becomes even more niche, because there's no way to enforce an order, whereas an ordered application of the expression would suffice even if we don't care about order.
So with C++17, I'd do it with a fold expression as follows
( (do_side_effect<T>(args), void()), ... );
, void()
is to ensure the type of each item in the pack doesn't interfere with the fold over a comma (since operator,
is overloadable). And then that expression is expanded with the comma operator ,
. You almost got there yourself, but it failed because you omitted the comma-operator.