【问题标题】:How to iterate over Variadic template types (not arguments)?如何迭代可变参数模板类型(不是参数)?
【发布时间】:2020-04-29 13:05:39
【问题描述】:

我正在编写一个期望可变数量的模板类型的类。我需要为每种类型调用一个订阅者,但请注意没有传递给类的实际参数。比如:

template<typename... T>
class Subscriber
{
    Subscriber()
    {
        // for(typename X: T)   <-- How to do this?
        // {
        //      PubSub.Subscribe<X>( [](auto data){ // do something with data} );
        // }
    }
}

【问题讨论】:

    标签: c++ templates c++14 variadic-templates


    【解决方案1】:

    在您的示例中,在 C++17 中,您可能会这样做:

    template<typename... Ts>
    class Subscriber
    {
        Subscriber()
        {
            auto f = [](auto data){ /* do something with data*/ };
            (PubSub.Subscribe<Ts>(f), ...);
        }
    }
    

    在 C++11/14 中,你可能会使用更详细的方式,例如:

    (C++14 目前使用你的通用 lambda)

    template<typename... Ts>
    class Subscriber
    {
        Subscriber()
        {
            auto f = [](auto data){ /* do something with data*/ };
            int dummy[] = {0, (PubSub.Subscribe<Ts>(f), void(), 0)...};
            static_cast<void>(dummy); // Avoid warning for unused variable.
        }
    }
    

    【讨论】:

    • 你的答案中的 X 是什么?
    • @NeilGatenby:一个错字。固定。
    • 为什么在0前加void()?为了避免operator,的陷阱?
    • @Evg:没错。理想情况下,我也应该为 C++17 版本这样做。
    • 包扩展仅限于几个地方,包括函数参数(f(args...)),initializer_list。前者不能保证从左到右的顺序,后者可以。 initializer_list 可以用来构造数组,所以int dummy = {(f&lt;Ts&gt;(), 0)...};(f&lt;Ts&gt;(), 0) 使用逗号确保返回类型为int。那么 void() 是处理邪恶的operator, 过载,额外的0, 是处理空包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多