user14416
user14416

Reputation: 3032

variadic template arguments unpacking

For each argument I need apply two nested function:

obj.apply(someFilter(arg)); // arg is one argument, but here
                            // should be an unpacking of args

I don't know how to write unpacking for such case.

I saw this:

 pass{([&]{ std::cout << args << std::endl; }(), 1)...};

on wiki, but again don't know how to apply this for my case.

Upvotes: 3

Views: 3815

Answers (3)

Grizzly
Grizzly

Reputation: 20191

It's actually quite simple: You can put arbitrary expression inside the unpack of an variadic templates argument pack:

obj.apply(someFilter(arg))...

This will give you the result of obj.apply as a coma seperated list. You can then pass it to a dummy function:

template<typename... Args> swallow (Args&&...) {}
swallow(obj.apply(someFilter(arg))...);

To swallow the comma seperated list.

Of course, this assumes that obj.apply returns some kind of object. If not you can use

swallow((obj.apply(someFilter(arg)), 0)...);

to make actual (non void) arguments

If you don't know what obj.apply` returns (result might have overloaded the comma operator), you can disable the use of custom comma operators by using

swallow((obj.apply(someFilter(arg)), void(),  0)...);

Should you actually need to evaluate the items in order (which doesn't seem very likely from the question), you can abuse array initialization syntax instead of using a function call:

using Alias=char[];
Alias{ (apply(someFilter(args)), void(), '\0')... };

Upvotes: 4

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275230

Here is a robust way to do an arbitrary set of actions on a parameter pack. It follows the principle of least surprise, and does the operations in order:

template<typename Lambda, typename Lambdas>
void do_in_order( Lambda&& lambda, Lambdas&& lambdas )
{
  std::forward<Lambda>(lambda)();
  do_in_order( std::forward<Lambdas>(lambdas)... );
}

void do_in_order() {}

template<typename Args>
void test( Args&& args ) {
  do_in_order( [&](){obj.apply(someFilter(std::forward<Args>(args)));}... );
}

Basically, you send a pile of lambdas at do_in_order, which evaluates them front to back.

Upvotes: 1

Daniel Frey
Daniel Frey

Reputation: 56863

I assume that the code has multiple args as a parameter pack? Try:

obj.apply( someFilter( arg )... );

as parameter unpacking applies to the expression, so each element of the parameter pack get's expanded into someFilter( arg ).

Upvotes: 0

Related Questions