我注意到开源项目中的以下行 FeatherKit :
int _[] = { (SubscribeToType<MessageTypes>( bus, receiver, desubscribers, unsubscribe ), 0)... };
具有以下上下文:
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;
}
很明显,它正在为可变参数模板中的每个参数执行函数 SubscribeToType。
我的问题有两个:
这条线路究竟是如何工作的?为什么参数解包允许该函数针对可变参数模板中的每个参数执行?
我非常确定这一行可以用 lambda 代替。如何用 lambda 表达式替换该行?
我已经联系了FeatherKit的原作者,但是他当时无法回答我的问题。
最佳答案
- How, exactly, does the line work? How come parameter unpacking is allowing that function to execute for each parameter in the variadic template?
参数包扩展是一些涉及参数包后跟 ...
的模式
所以 expr(T)...
是 expr(T)
的扩展包作为它的模式,它扩展为 expr(T0), expr(T1), expr(T2), ..., expr(TN)
对于每个 Ti
在参数包中。
包扩展只能在某些上下文中使用,例如参数列表或初始化列表,因此在这种情况下,每个子表达式的结果用于形成数组 int _[]
的初始化列表。 .该数组未使用,仅存在以便其初始化程序可用作执行包扩展的上下文。每个子表达式的形式都是 (SubscribeToType<Ti>(blah, blah), 0)
这意味着函数调用的结果被丢弃,表达式的值为 0。这有点麻烦,允许包扩展生成包含 N 个整数的花括号初始化列表,因为这是初始化数组所需要的.
- I am very certain this line could be replaced by a lambda. How could you replace the line with a lambda expression?
为什么要这么做?
可以,但是您需要在 lambda 中进行非常相似的包扩展,因此它不会简化任何事情。
关于c++ - 为可变参数模板中的每个打包参数执行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27400305/