【问题标题】:Executing function for each packed parameter in variadic template为可变参数模板中的每个打包参数执行函数
【发布时间】:2014-12-11 00:22:26
【问题描述】:

我注意到开源项目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 的原作者,但当时他无法回答我的问题。

【问题讨论】:

    标签: c++ lambda variadic-templates


    【解决方案1】:
    1. 这条线路究竟是如何工作的?为什么参数解包允许该函数为可变参数模板中的每个参数执行?

    参数包扩展是一些涉及参数包后跟...的模式

    所以expr(T)...是以expr(T)为模式的包扩展,对于参数包中的每个Ti,它都扩展为expr(T0), expr(T1), expr(T2), ..., expr(TN)

    包扩展只能在某些上下文中使用,例如参数列表或初始化列表,因此在这种情况下,每个子表达式的结果都被用于形成数组int _[] 的初始化列表。该数组未使用且仅存在以便其初始化程序可用作进行包扩展的上下文。每个子表达式的形式为(SubscribeToType&lt;Ti&gt;(blah, blah), 0),这意味着函数调用的结果被丢弃,表达式的值为0。这有点麻烦,允许包扩展产生一个包含N 个整数,因为这是初始化数组所需要的。

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

    你为什么想要?

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

    【讨论】:

    • 为了解决第 2 点,我觉得使用 int 数组的初始化程序有点“hack”,而且不是很干净。我认为迭代参数包的 lambda 对读者来说会非常干净和清晰。
    • 您将如何“迭代”整个包?请记住,它是一组类型,您没有可以实际传递给 lambda 的参数包。该数组很老套,但仅仅说“使用 lambda”并不能提供更简洁的解决方案(或任何解决方案;-)
    • 你说得对,我只是觉得一定有一个更干净的解决方案,我不知道为包中的每个参数执行函数调用。我现在知道了:)
    猜你喜欢
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2021-02-11
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多