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
相关产品推荐
相关产品推荐

