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

基于模板类型条件初始化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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:52:12