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?
CodePudding user response:
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 andbool EmplaceAllProcessor()
to tell if all theEmplaceProcessor
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;
}