C++如何通过模板为不同类型映射对应类型常量消除重复代码
问题原因
代码编译失败的核心错误是混淆了模板默认参数和模板全特化的语法:
- 重复定义了同名的
jqx_type主模板,C++不允许同一作用域下存在多个同名主模板 - 针对特定类型做类型映射需要使用模板全特化语法,而非给模板参数加默认值
- long类型的实现误将结构体名写为
jqx_types,多了一个s,即使前面语法正确也无法完成匹配。
正确实现方式
只需要保留一个主模板,针对每个需要映射的C++类型写全特化版本即可:
// 主模板:未做特化的类型默认返回JQX_TYPE_NONE template<typename T> struct jqx_type { static const int type = JQX_TYPE_NONE; }; // int类型特化 template<> struct jqx_type<int> { static const int type = JQX_TYPE_INT; }; // long类型特化 template<> struct jqx_type<long> { static const int type = JQX_TYPE_LONG; }; // double类型特化 template<> struct jqx_type<double> { static const int type = JQX_TYPE_DOUBLE; }; // float、char等其他类型按照上述格式补充特化即可
修正createObject函数里的笔误(多写的尖括号、tyepename拼写错误),就可以直接使用:
template<typename T> myObj *createObject(int iSize) { int iRealSize = calcEffectiveSize(iSize, jqx_type<T>::type); return new myObj(iRealSize); }
调用时不需要传入哑变量,直接指定模板参数即可:
// 等价于原int版本的createObject myObj* intObj = createObject<int>(1024); // 等价于原double版本的createObject myObj* doubleObj = createObject<double>(2048);
简化写法(C++17及以上可用)
如果编译环境支持C++17,可以额外定义变量模板,省略每次书写::type的麻烦:
template<typename T> inline constexpr int jqx_type_v = jqx_type<T>::type; // 函数内可以直接简写为 int iRealSize = calcEffectiveSize(iSize, jqx_type_v<T>);
内容的提问来源于stack exchange,提问作者user1479670
相关产品推荐
相关产品推荐

