简体   繁体   中英

Executing function for each packed parameter in variadic template

I noticed the following line in the open-source project FeatherKit :

int _[] = { (SubscribeToType<MessageTypes>( bus, receiver, desubscribers, unsubscribe ), 0)... };

With the following context:

template<class... MessageTypes>
void Subscribe( MessageBus& bus, MessageReceiver<MessageTypes...>& receiver, bool unsubscribe ) {
    std::vector<std::function<void()>> desubscribers;
    int _[] = { (SubscribeToType<MessageTypes>( bus, receiver, desubscribers, unsubscribe ), 0)... };
    (void) _;
    receiver.desubscribers = desubscribers;
}

It's obviously executing the function SubscribeToType for each parameter in the variadic template.

My question is twofold:

  1. How, exactly, does the line work? How come parameter unpacking is allowing that function to execute for each parameter in the variadic template?

  2. I am very certain this line could be replaced by a lambda. How could you replace the line with a lambda expression?

I've contacted the original author of FeatherKit, but he wasn't able to answer my question at that time.

  1. How, exactly, does the line work? How come parameter unpacking is allowing that function to execute for each parameter in the variadic template?

A parameter pack expansion is some pattern involving a parameter pack followed by ...

So expr(T)... is a pack expansion with expr(T) as its pattern, and it expands to expr(T0), expr(T1), expr(T2), ..., expr(TN) for each Ti in the parameter pack.

A pack expansion can only be used in certain contexts, such as argument lists, or initializer lists, so in this case the results of each sub-expression is being used to form an initializer list for the array int _[] . The array is unused and only exists so that its initializer can be used as the context in which to do the pack expansion. Each sub-expression is of the form (SubscribeToType<Ti>(blah, blah), 0) which means the result of the function call is discarded and the expression has the value 0. This is a bit of a kluge to allow the pack expansion to produce a braced-init-list containing N integers, because that's what's needed to initialize the array.

  1. I am very certain this line could be replaced by a lambda. How could you replace the line with a lambda expression?

Why would you want to?

It could, but you'd need a very similar pack expansion in the lambda, so it wouldn't simplify anything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM