C++中如何展开模板参数包实现批量添加处理器?
问题
现有针对类型T的模板函数EmplaceProcessor,代码如下:
template <class T> void EmplaceProcessor() { T* pProcessor = new T(); m_vItemProcessors.emplace_back(pProcessor); }
希望实现一个批量添加多种类型到vector的函数,尝试编写的模板函数如下,但不知道如何正确展开参数包:
template<class...A> void EmplaceAllProcessor() { const int size = sizeof...(A); for (int i = 0; i < size; ++i) { EmplaceProcessor<A[i]>(); //how to expand it????? } }
需要通过调用EmplaceAllProcessor<P1, P2, P3>()来批量添加对应类型的处理器,请问该如何正确实现?
解决方案
你原写法的核心问题是:模板参数包A是编译期类型集合,无法像运行期数组那样用A[i]访问。必须通过编译期参数包展开的方式逐个调用EmplaceProcessor,下面提供几种可行方案:
方案1:C++11/14 递归展开(兼容旧标准)
通过递归模板函数逐个拆解参数包,直到包为空:
// 递归终止函数:参数包为空时触发 void EmplaceAllProcessor() {} // 递归展开函数:每次处理第一个类型,再递归处理剩余参数 template<class First, class... Rest> void EmplaceAllProcessor() { EmplaceProcessor<First>(); EmplaceAllProcessor<Rest...>(); }
调用方式不变,编译时会自动生成EmplaceProcessor<P1>()、EmplaceProcessor<P2>()、EmplaceProcessor<P3>()的连续调用代码。
方案2:C++17 折叠表达式(更简洁)
C++17引入的折叠表达式可以直接展开参数包,无需递归:
template<class...A> void EmplaceAllProcessor() { // 逗号折叠表达式,确保每个EmplaceProcessor被依次调用 (EmplaceProcessor<A>(), ...); }
这里的逗号运算符会按顺序执行每个EmplaceProcessor调用,写法更简洁直观。
额外优化:避免裸指针(可选)
如果项目允许,建议用智能指针替代裸指针,消除内存泄漏风险:
#include <memory> // 修改EmplaceProcessor template <class T> void EmplaceProcessor() { // 假设m_vItemProcessors的类型是std::vector<std::unique_ptr<YourBaseProcessor>> m_vItemProcessors.emplace_back(std::make_unique<T>()); }
内容的提问来源于stack exchange,提问作者Kendy Xicor
相关产品推荐
相关产品推荐

