Kendy Xicor
Kendy Xicor

Reputation: 33

Expand template class list in C++

I have a template function to do sth with type T

template <class T>
void EmplaceProcessor()
{
    T* pProcessor = new T();
    m_vItemProcessors.emplace_back(pProcessor);
}

If I want to implement a lot of types to emplace to the vector, just sth like:

template<class...A> 
void EmplaceAllProcessor()
{
    const int size = sizeof...(A);
    for (int i = 0; i < size; ++i)
    {
        EmplaceProcessor<A[i]>();     //how to expand it?????
    }
}

and I want to call EmplaceAllProcessor<P1, P2, P3>(); to emplace all types of processor

I want to call EmplaceAllProcessor<P1, P2, P3>(); to emplace all types of processor, How can it be?

Upvotes: 3

Views: 143

Answers (1)

Evg
Evg

Reputation: 26302

In C++11, you can use a dummy array initialization trick:

template<class... A> 
void EmplaceAllProcessor() {
    int dummy[] = {0, (EmplaceProcessor<A>(), 0)...};
    (void)dummy;
}

A comma operator expression is used to invoke EmplaceProcessor<A>() for each type in the pack A..., in order (the order of evaluation of arguments in a braced list is fixed by their order in that list per [dcl.init.list/4]). The first 0 is needed to support an empty pack and (void)dummy; suppresses an unused variable warning.

If I want to return a value, for example: bool EmplaceAllProcessor() to return whether it is succeeded and bool EmplaceAllProcessor() to tell if all the EmplaceProcessor work succeeded, how can it be?

If you don't need short circuiting, it's a simple extension of the above approach:

template<class... A> 
bool EmplaceAllProcessor() {
    bool res[] = {true, EmplaceProcessor<A>()...};
    return std::all_of(std::begin(res), std::end(res), [](bool b) { return b; });
}

If short circuiting is needed, another small trick might be used:

template<class... A> 
bool EmplaceAllProcessor() {
    bool res = true;
    bool dummy[] = {true, (res = res && EmplaceProcessor<A>())...};
    (void)dummy;
    return res;
}

Upvotes: 6

Related Questions