6

Did some searching and couldn't find an answer to this question so apologies if a repost. I want to call the same function with the same arg on a bunch of different objects. I currently implemented it like this:

void callWithArg(const char* msg) { }

template <typename HEAD, typename.... TAIL>
void callWithArg(HEAD&& head, TAIL&&... tail, const char* msg) {
    head.foo(msg);
    callWithArg(tail..., msg);
}

Obviously that in itself is not a particularly tedious bit of code, I was just wondering if there was a simpler or cleaner way of iterating over that parameter pack than this kind of recursive invocation? Thanks!

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
Barry
  • 286,269
  • 29
  • 621
  • 977
  • 2
    Hopefully [this Q&A](http://stackoverflow.com/questions/14261183/how-to-make-generic-computations-over-heterogeneous-argument-packs-of-a-variadic) can help – Andy Prowl Feb 13 '13 at 16:16
  • 1
    It depends a lot whether you care about the order in which the iteration is done or not. – Marc Glisse Feb 13 '13 at 16:28
  • The solution proposed by @MarcGlisse in the linked Q&A is simple and effective. If you want a more powerful and generalized processing, then you can take my framework as an inspiration – Andy Prowl Feb 13 '13 at 16:31

1 Answers1

2

Here's the most concise way I know to express this:

template<typename ...T>
void callWithArg(const char *msg, T &&...t) {
  int dummy[] = { 0, (t.foo(msg), 0)... };
}

The pack expansion expands to a list of expressions of type int, which are used to initialize the array dummy (which we throw away). The calls to foo are sequenced, because in C++11, elements of a list-initialization are sequenced left-to-right.

If you add a #include <initializer_list>, you can slightly simplify this to:

auto dummy = { 0, (t.foo(msg), 0)... };

You may also want to suppress the "unused variable" warning which various compilers produce on this code, with

(void) dummy;

The initial 0, is included to avoid an error if the function is given no arguments other than msg. I also reordered your function's parameters to put the pack last, so that the types in the pack can be deduced.

Richard Smith
  • 13,696
  • 56
  • 78