3

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?

Aamir
  • 1,974
  • 1
  • 14
  • 18
  • 2
    Are you really limited to C++11? – user17732522 Jan 09 '23 at 03:04
  • C++14 is ok. not C++17 and later – Kendy Xicor Jan 09 '23 at 03:13
  • Just an aside @KendyXicor . Please don't use naked new and delete. At least use `std::unique_ptr` https://en.cppreference.com/w/cpp/memory/unique_ptr . – Alexander Kondratskiy Jan 09 '23 at 03:38
  • @AlexanderKondratskiy he might not have it because platform or standard support, especially with compiler which doesn't have user-space atomic – Swift - Friday Pie Jan 09 '23 at 06:14
  • 1
    @Swift-FridayPie You are right. unique_ptr is not allowed for we have our own memory allocator, actually the new operator is undefined and the code is indicative only. – Kendy Xicor Jan 09 '23 at 07:38
  • I think your question is duplicate. Please find the answers here https://stackoverflow.com/questions/25680461/variadic-template-pack-expansion – Ionut Alexandru Jan 09 '23 at 15:07
  • @KendyXicor `new` can be re-defined\overloaded using custom allocator as well as standard library can be used with custom allocator. Why that decision to not use it? In that case you cannot use any of standard library components. "undefined" new operator - i's either a custom\non-standard compiler is used or something leading to UB is happening and then all guarantees are defenestrated, including the fact that any answer you get on this site or anywhere in Internet might not be not right unless you specify what compiler you're using. – Swift - Friday Pie Jan 10 '23 at 08:28
  • @Swift-FridayPie a third party library undefined new operator and we should use macro such as "My_NEW(allocator, type) instead, and "My_DELETE(allocator, pobject)" should be called manually. Ofcourse, I can use std::unique_ptr with custom deleter, and include other header using operator new with pushing the "new" temperally using #pragma. – Kendy Xicor Jan 12 '23 at 07:08

1 Answers1

6

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;
}
Evg
  • 25,259
  • 5
  • 41
  • 83
  • Thanks, It Works! If I wanr to return a value, for example: bool EmplaceAllProcessor() to return whether it is succeeded. and bool EmplaceAllProcessor() to tell if all the Emplace work suceeded, how can it be? – Kendy Xicor Jan 09 '23 at 03:21