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

C++中运行时生成的整数能否作为模板参数使用?

你要实现的是运行时动态值到编译期模板参数的映射,不需要手动写switch分支,通过编译期展开自动生成跳转表即可,C++11及以上版本都支持该方案,不需要改动原有类和枚举的定义。

注意:你提供的示例代码中Foo类模板没有继承Base,需要先补上继承关系,否则无法将Foo<i>实例的指针存入std::unique_ptr<Base>。

完整实现代码

#include <memory>
#include <utility>
#include <array>
#include <cstdlib>

class Base
{
};

// 补上继承关系
template<int i>
class Foo : public Base
{
};

namespace SomeEnum
{
enum
{
    First,
    Second,
    Third,
    Last
};
}

// 编译期生成所有Foo实例的工厂函数数组
template<std::size_t... Is>
auto make_foo_factory(std::index_sequence<Is...>)
{
    return std::array{
        []() -> std::unique_ptr<Base> {
            return std::make_unique<Foo<Is>>();
        }...
    };
}

// 全局工厂表,编译阶段自动生成所有枚举值对应的实例化逻辑
constexpr auto foo_factory = make_foo_factory(std::make_index_sequence<SomeEnum::Last>{});

void bar()
{
    std::unique_ptr<Base> ptr{ nullptr };
    int fooType = rand() % SomeEnum::Last;
    // 运行时直接调用对应工厂即可,无需手动写分支
    ptr = foo_factory[fooType]();
}

方案说明

  • 核心逻辑是通过std::index_sequence生成从0到SomeEnum::Last - 1的编译期整数序列,利用可变参数展开为每个整数生成对应的lambda工厂函数,存入静态数组
  • 运行时直接用拿到的fooType作为下标调用对应工厂函数即可完成实例化,本质和手写switch的性能完全一致,属于同等级别的跳转表实现
  • 后续新增枚举成员不需要改动工厂代码,只要更新SomeEnum中Last的值,编译器会自动生成对应新枚举值的实例化逻辑
  • 如果使用C++11标准,自行实现简易版index_sequence工具类即可复用该逻辑,代码复杂度很低

内容的提问来源于stack exchange,提问作者JensB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:06:02