C++17 如何通过非类型模板参数实现工厂创建对应模板实例
问题分析
你的代码存在3个核心编译错误和逻辑问题:
Body是带模板参数的模板类,不存在Body<>这种无参特化,直接声明unique_ptr<Body<>>属于语法错误- 不同参数的
Body<Part1>和Body<Part2>是完全独立的类型,没有公共父类的情况下无法用同一种指针类型作为返回值 - 模板内用普通
if判断编译期常量e时,两个分支都会被实例化,必然会出现其中一个分支返回值和声明返回类型不匹配的问题
修正方案
方案1:C++17及以上版本实现(最简洁)
核心修改点:
- 新增公共基类
BodyBase,所有Body特化类继承该基类,统一返回值类型 - 使用
if constexpr在编译期裁剪分支,避免无效分支实例化 - 修正工厂返回值和调用逻辑
完整可运行代码:
#include <memory> using namespace std; // 新增公共基类 class BodyBase { public: virtual ~BodyBase() = default; // 必须加虚析构保证子类资源正确释放 }; template<typename Part> class Body : public BodyBase {}; class Part1 {}; class Part2 {}; enum class E { part1, part2, }; template<E e> class Factory { public: // 返回值改为基类指针 static unique_ptr<BodyBase> create() { // 编译期分支裁剪 if constexpr (e == E::part1) { return make_unique<Body<Part1>>(); } else { return make_unique<Body<Part2>>(); } } }; int main() { // 调用静态create方法获取实例 auto body1 = Factory<E::part1>::create(); auto body2 = Factory<E::part2>::create(); return 0; }
方案2:兼容C11/C14的模板特化实现
如果无法使用C++17的if constexpr,可以用模板全特化实现工厂逻辑:
// 前置声明工厂类 template<E e> class Factory; // 特化part1的实现 template<> class Factory<E::part1> { public: static unique_ptr<BodyBase> create() { return make_unique<Body<Part1>>(); } }; // 特化part2的实现 template<> class Factory<E::part2> { public: static unique_ptr<BodyBase> create() { return make_unique<Body<Part2>>(); } };
调用方式和方案1完全一致。
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

