基于模板类型条件初始化C++类成员变量(兼容C++11)
兼容C++11的模板依赖数组初始化方案
以下三种方案均满足你的需求,可根据代码复杂度选择合适的实现方式:
方法一:类模板全特化
直接针对不同Type枚举值特化整个类,每个特化版本定义对应类型、长度和初始值的arr成员,直观易懂,适合枚举值较少的场景:
#include <cstdint> enum class Type { Type32, Type64 }; // 前置声明模板类 template<Type T> class MyClass; // 特化Type::Type32版本 template<> class MyClass<Type::Type32> { public: using MyType = uint32_t; MyType getSum() { MyType sum = 0; // 修正原代码的循环边界错误:用元素个数而非字节数 const size_t arrSize = sizeof(arr) / sizeof(arr[0]); for(size_t i = 0; i < arrSize; ++i) { sum += arr[i]; } return sum; } private: MyType arr[4] = { 0x1234, 0x5678, 0x9ABC, 0xDEF0 }; }; // 特化Type::Type64版本 template<> class MyClass<Type::Type64> { public: using MyType = uint64_t; MyType getSum() { MyType sum = 0; const size_t arrSize = sizeof(arr) / sizeof(arr[0]); for(size_t i = 0; i < arrSize; ++i) { sum += arr[i]; } return sum; } private: MyType arr[2] = { 0x12345678, 0x9ABCDEF0 }; };
方法二:基类复用公共逻辑+派生类特化
将公共接口(如MyType别名、getSum方法)提取到基类,派生类仅特化arr成员,避免代码重复,更利于维护:
#include <cstdint> #include <type_traits> enum class Type { Type32, Type64 }; // 基类:包含公共逻辑 template<Type T> class MyClassBase { public: using MyType = typename std::conditional<T == Type::Type32, uint32_t, uint64_t>::type; MyType getSum(); }; // 通用派生类模板(留空,仅用于特化) template<Type T> class MyClass : public MyClassBase<T> {}; // Type::Type32的派生类特化 template<> class MyClass<Type::Type32> : public MyClassBase<Type::Type32> { private: MyType arr[4] = { 0x1234, 0x5678, 0x9ABC, 0xDEF0 }; // 允许基类访问私有成员arr friend MyType MyClassBase<Type::Type32>::getSum(); }; // Type::Type64的派生类特化 template<> class MyClass<Type::Type64> : public MyClassBase<Type::Type64> { private: MyType arr[2] = { 0x12345678, 0x9ABCDEF0 }; friend MyType MyClassBase<Type::Type64>::getSum(); }; // 实现基类的getSum方法 template<Type T> typename MyClassBase<T>::MyType MyClassBase<T>::getSum() { MyType sum = 0; auto& arr = static_cast<MyClass<T>*>(this)->arr; const size_t arrSize = sizeof(arr) / sizeof(arr[0]); for(size_t i = 0; i < arrSize; ++i) { sum += arr[i]; } return sum; }
方法三:用std::array结合特性类(更现代化)
借助std::array和特性类封装不同类型的数组信息,避免原生数组的边界计算错误,同时保持代码一致性:
#include <cstdint> #include <array> #include <type_traits> enum class Type { Type32, Type64 }; // 特性类:定义不同Type对应的数组类型和初始值 template<Type T> struct ArrayTraits; template<> struct ArrayTraits<Type::Type32> { using ValueType = uint32_t; static constexpr std::array<ValueType, 4> initValue = {{0x1234, 0x5678, 0x9ABC, 0xDEF0}}; }; template<> struct ArrayTraits<Type::Type64> { using ValueType = uint64_t; static constexpr std::array<ValueType, 2> initValue = {{0x12345678, 0x9ABCDEF0}}; }; template<Type T> class MyClass { public: using MyType = typename ArrayTraits<T>::ValueType; using ArrayType = decltype(ArrayTraits<T>::initValue); MyType getSum() { MyType sum = 0; // 直接用std::array的size()方法获取元素个数 for(size_t i = 0; i < arr.size(); ++i) { sum += arr[i]; } return sum; } private: ArrayType arr = ArrayTraits<T>::initValue; };
注意事项
- 原代码中的
for循环条件存在错误:i < sizeof(arr)会遍历字节数而非元素个数,导致数组越界,需修正为sizeof(arr)/sizeof(arr[0])(原生数组)或arr.size()(std::array)。 - 上述三种方法均完全兼容C++11标准。
内容的提问来源于stack exchange,提问作者folibis
相关产品推荐
相关产品推荐

