variadic template arguments unpacking

江枫思渺然 提交于 2019-12-05 02:12:57

问题


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.


回答1:


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')... };



回答2:


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 ).




回答3:


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.



来源:https://stackoverflow.com/questions/15276991/variadic-template-arguments-unpacking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!