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

C++ 如何通过运行时char值映射对应单字符命名类,用模板获取sizeof

问题原因说明

模板参数必须是编译期常量,你代码里的testChar是运行时变量,无法直接作为模板参数传入printSize。

实现方案

提前构建「字符值-对应类的大小打印函数」的静态映射表,运行时直接查表调用即可。通过可变参数模板批量注册所有目标类,不需要手动写switch/case或if/else分支枚举类型。

完整实现代码(C++17及以上版本)

#include <iostream>
#include <unordered_map>

// 示例类定义,可扩展更多单字符命名类
class A
{
private:
    char name;
public:
    A(){name='A';}
    char getName(){return name;}
};

class B
{
private:
    char name;
    int dummy;
public:
    B(){name='B';}
    char getName(){return name;}
};

class C
{
private:
    char name;
    double dummy;
public:
    C(){name='C';}
    char getName(){return name;}
};

template <typename X>
void printSize()
{
    X newObject;
    std::cout << sizeof(newObject) << std::endl;
}

// 批量构建映射表
template<typename... Ts>
std::unordered_map<char, void(*)()> buildSizeLookup()
{
    std::unordered_map<char, void(*)()> lookup;
    // 折叠表达式自动展开所有模板参数,批量注册处理函数
    (..., [&](){
        Ts tmpObj;
        lookup[tmpObj.getName()] = &printSize<Ts>;
    }());
    return lookup;
}

// 全局静态查找表,新增类只需要在模板参数列表追加类名即可
const static auto g_sizeLookup = buildSizeLookup<A, B, C>();

int main()
{
    char testChar = 'B'; // 可替换为任意运行时生成的合法char值
    // 查表调用,如需处理不存在的字符可先调用g_sizeLookup.contains(testChar)做判断
    g_sizeLookup.at(testChar)();
    return 0;
}

C++11/14兼容版本

如果使用低于C++17的版本,把buildSizeLookup的折叠表达式部分替换为初始化列表展开即可:

template<typename... Ts>
std::unordered_map<char, void(*)()> buildSizeLookup()
{
    std::unordered_map<char, void(*)()> lookup;
    // C++11/14兼容的参数包展开写法
    int dummy[] = {0, ( [&](){
        Ts tmpObj;
        lookup[tmpObj.getName()] = &printSize<Ts>;
    }(), 0)... };
    (void)dummy; // 避免未使用变量警告
    return lookup;
}

注意事项

  • 新增单字符命名类时,只需要在buildSizeLookup的模板参数列表里追加类名即可,不需要修改其他逻辑
  • 若传入的char没有对应的类,at方法会抛出std::out_of_range异常,可根据业务需求自行增加判断逻辑处理异常场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:45:06