可变参数模板中每个打包参数的执行函数

Executing function for each packed parameter in variadic template

本文关键字:参数 执行 函数 包参数 变参      更新时间:2023-10-16

我在开源项目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。

我的问题是双重的:

  1. 这条生产线究竟是如何工作的?为什么参数解包允许该函数为可变参数模板中的每个参数执行?

  2. 我非常确定这条线可以用 lambda 代替。如何将该行替换为 lambda 表达式?

我已经联系了FeatherKit的原作者,但他当时无法回答我的问题。

  1. 这条生产线究竟是如何工作的?为什么参数解包允许该函数为可变参数模板中的每个参数执行?
参数包

扩展是涉及参数包后跟...的某种模式

因此expr(T)...是以expr(T)为模式的包扩展,它针对参数包中的每个Ti扩展到expr(T0), expr(T1), expr(T2), ..., expr(TN)

包扩展只能在某些上下文中使用,例如参数列表或初始值设定项列表,因此在这种情况下,每个子表达式的结果都用于形成数组int _[]的初始值设定项列表。数组未使用,仅存在,以便其初始值设定项可用作执行包扩展的上下文。 每个子表达式的格式都是(SubscribeToType<Ti>(blah, blah), 0)这意味着函数调用的结果将被丢弃,表达式的值为 0。这有点麻烦,允许包扩展生成包含 N 个整数的大括号 init-list,因为这是初始化数组所需的。

  1. 我非常确定这条线可以用 lambda 代替。如何将该行替换为 lambda 表达式?

你为什么要这样做?

它可以,但你需要在lambda中进行非常相似的包扩展,所以它不会简化任何东西。