简体   繁体   English

在可变参数模板中为每个压缩参数执行函数

[英]Executing function for each packed parameter in variadic template

I noticed the following line in the open-source project FeatherKit : 我注意到开源项目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. 它显然是为可变参数模板中的每个参数执行函数SubscribeToType。

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. 我非常肯定这条线可以用lambda代替。 How could you replace the line with a lambda expression? 你怎么能用lambda表达式替换该行?

I've contacted the original author of FeatherKit, but he wasn't able to answer my question at that time. 我已经联系了FeatherKit的原作者,但他当时无法回答我的问题。

  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. 所以expr(T)...是一个以expr(T)为模式的包扩展,它扩展为expr(T0), expr(T1), expr(T2), ..., expr(TN)参数包中的Ti

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 _[] . 包扩展只能在某些上下文中使用,例如参数列表或初始化列表,因此在这种情况下,每个子表达式的结果用于形成数组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. 每个子表达式都是这样的形式(SubscribeToType<Ti>(blah, blah), 0)这意味着函数调用的结果被丢弃,表达式的值为0.这是一个允许包装的一点点扩展以生成包含N个整数的braced-init-list,因为这是初始化数组所需要的。

  1. I am very certain this line could be replaced by a lambda. 我非常肯定这条线可以用lambda代替。 How could you replace the line with a lambda expression? 你怎么能用lambda表达式替换该行?

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. 它可以,但你需要在lambda中进行非常类似的包扩展,所以它不会简化任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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