You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++17 如何通过非类型模板参数实现工厂创建对应模板实例

问题分析

你的代码存在3个核心编译错误和逻辑问题:

  • Body是带模板参数的模板类,不存在Body<>这种无参特化,直接声明unique_ptr<Body<>>属于语法错误
  • 不同参数的Body<Part1>和Body<Part2>是完全独立的类型,没有公共父类的情况下无法用同一种指针类型作为返回值
  • 模板内用普通if判断编译期常量e时,两个分支都会被实例化,必然会出现其中一个分支返回值和声明返回类型不匹配的问题
修正方案

方案1:C++17及以上版本实现(最简洁)

核心修改点:

  1. 新增公共基类BodyBase,所有Body特化类继承该基类,统一返回值类型
  2. 使用if constexpr在编译期裁剪分支,避免无效分支实例化
  3. 修正工厂返回值和调用逻辑

完整可运行代码:

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:57:03