简体   繁体   English

如何扩展可变参数模板 class

[英]How to expand variadic template class

Simplified I'm trying the following:简化我正在尝试以下操作:

template<typename T>
struct SomeObject
{
    T value;
};

template<typename... Ts>
struct Container : public SomeObject<Ts>...
{
    void init()
    {
        (initObject<Ts>())...; // not working: how to execute initObject for each type
    }

    template<typename T>
    void initObject()
    {
        SomeObject<T>::value = new T();
        // do some other stuff
    }
};

class A {};
class B {};

int main()
{
    auto c = new Container<A, B>();
    c->init();
}

In my use case I cannot do the initialization in the constructor.在我的用例中,我无法在构造函数中进行初始化。 So how can I get the init method to properly expand for all types?那么我怎样才能让init方法正确地扩展所有类型呢?

In c++17, you can do it with a fold expression over the comma operator在 c++17 中,您可以在逗号运算符上使用折叠表达式来完成

(initObject<Ts>(), ...);

before c++17 you could do something like在 c++17 之前你可以做类似的事情

std::initializer_list<int>{(initObject<Ts>(), 0)...};

Note the comma experssion in the initializer list.注意初始化列表中的逗号表达式。 It is there because initObject returns void , and you cannot have an initializer_list of void s它在那里是因为initObject返回void ,并且您不能拥有voidinitializer_list

Here is another more general solution.这是另一个更通用的解决方案。 It is too complex for this case, but may be useful.对于这种情况,它太复杂了,但可能很有用。

template<typename... Ts>
struct Container : public SomeObject<Ts>...
{
    void init()
    {
        initObjects<Ts...>(); // not working: how to execute initObject for each type
    }

    template <typename ...Args>
    struct object_initializer;

    template <typename First, typename ...Rest>
    struct object_initializer<First, Rest...> {
        void operator ()() {
            SomeObject<First> obj{First()};
            object_initializer<Rest...>()();
        }
    };

    template <typename First>
    struct object_initializer<First> {
        void operator ()() {
            SomeObject<First> obj{First()};
        }
    };

    template<typename ...Args>
    void initObjects() {
        object_initializer<Args...>()();
    }
};

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

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