如何根据模板类型TypeA间接变更类成员变量的类型?
实现依赖模板参数的成员类型映射
你可以通过类模板全特化或者**类型特性(Type Traits)**两种方式实现这个需求,以下是具体方案:
方案一:类模板全特化
直接针对每个目标TypeA类型,特化整个A_class类,在特化版本中明确指定TypeB和TypeC的类型:
#include <string> // 主模板声明(仅做占位,无需定义) template<typename TypeA> class A_class; // 特化:当TypeA为int时 template<> class A_class<int> { public: using TypeB = double; using TypeC = std::string; // 示例成员变量 TypeB b; TypeC c; }; // 特化:当TypeA为double时 template<> class A_class<double> { public: using TypeB = std::string; using TypeC = int; TypeB b; TypeC c; }; // 特化:当TypeA为string时 template<> class A_class<std::string> { public: using TypeB = int; using TypeC = double; TypeB b; TypeC c; };
这种方式逻辑直接,每个特化版本独立定义对应类型,可读性强,适合类型映射规则固定的场景。
方案二:类型特性(Type Traits)
将类型映射逻辑抽离到单独的特性类中,A_class通过特性类间接获取TypeB和TypeC,扩展性更好:
#include <string> // 类型特性模板声明 template<typename TypeA> struct A_type_traits; // 特化特性类:int -> double/string template<> struct A_type_traits<int> { using TypeB = double; using TypeC = std::string; }; // 特化特性类:double -> string/int template<> struct A_type_traits<double> { using TypeB = std::string; using TypeC = int; }; // 特化特性类:string -> int/double template<> struct A_type_traits<std::string> { using TypeB = int; using TypeC = double; }; // 主模板类,基于特性类获取成员类型 template<typename TypeA> class A_class { public: using TypeB = typename A_type_traits<TypeA>::TypeB; using TypeC = typename A_type_traits<TypeA>::TypeC; TypeB b; TypeC c; };
如果后续需要新增TypeA的类型映射,只需添加对应的A_type_traits特化,无需修改A_class的核心代码,更符合开闭原则。
使用示例
两种方案的使用方式完全一致:
int main() { A_class<int> a_int; a_int.b = 3.14; // 类型为double a_int.c = "test"; // 类型为std::string A_class<double> a_double; a_double.b = "hello"; // 类型为std::string a_double.c = 42; // 类型为int A_class<std::string> a_str; a_str.b = 100; // 类型为int a_str.c = 2.718; // 类型为double return 0; }
不推荐的方式:嵌套std::conditional
虽然C++17后可以用std::conditional_t嵌套实现类型选择,但代码会变得冗长且可读性差,仅适合简单场景:
#include <string> #include <type_traits> template<typename TypeA> class A_class { public: using TypeB = std::conditional_t< std::is_same_v<TypeA, int>, double, std::conditional_t< std::is_same_v<TypeA, double>, std::string, std::conditional_t<std::is_same_v<TypeA, std::string>, int, void> > >; using TypeC = std::conditional_t< std::is_same_v<TypeA, int>, std::string, std::conditional_t< std::is_same_v<TypeA, double>, int, std::conditional_t<std::is_same_v<TypeA, std::string>, double, void> > >; TypeB b; TypeC c; };
内容的提问来源于stack exchange,提问作者carmiac
相关产品推荐
相关产品推荐

