如何遍历枚举并累加同名类的sizeof值(编译期实现)
编译期计算枚举对应类的sizeof总和实现方案
下面提供几种基于模板元编程、C++17 constexpr特性及预处理器的实现方案,均能在编译期完成sizeof值的求和计算:
方法一:模板元编程递归求和
通过模板特化建立枚举与对应类的映射,再用递归模板遍历枚举值累加sizeof:
#include <cstddef> enum class Enum { First, A = First, B, C, Last }; class A { int x; }; class B { double y; char z; }; class C { long long w; }; // 枚举到对应类的映射模板 template<Enum E> struct EnumToType; template<> struct EnumToType<Enum::A> { using Type = A; }; template<> struct EnumToType<Enum::B> { using Type = B; }; template<> struct EnumToType<Enum::C> { using Type = C; }; // 递归求和模板 template<Enum Current, Enum End> struct SumSizeOf { static constexpr size_t value = sizeof(typename EnumToType<Current>::Type) + SumSizeOf<static_cast<Enum>(static_cast<int>(Current)+1), End>::value; }; // 递归终止条件:遍历到Last时返回0 template<Enum End> struct SumSizeOf<End, End> { static constexpr size_t value = 0; }; constexpr size_t GetTotSumSizeOf() { return SumSizeOf<Enum::First, Enum::Last>::value; } static constexpr size_t TotSum = GetTotSumSizeOf(); // 编译期直接计算完成
方法二:C++17 constexpr折叠表达式
利用C++17的编译期折叠表达式,配合枚举列表直接展开求和,代码更简洁:
#include <cstddef> enum class Enum { First, A = First, B, C, Last }; class A { int x; }; class B { double y; char z; }; class C { long long w; }; // 枚举到类的映射 template<Enum E> struct EnumToType; template<> struct EnumToType<Enum::A> { using Type = A; }; template<> struct EnumToType<Enum::B> { using Type = B; }; template<> struct EnumToType<Enum::C> { using Type = C; }; // 折叠表达式展开求和 template<Enum... Es> constexpr size_t sum_sizes() { return (sizeof(typename EnumToType<Es>::Type) + ...); } static constexpr size_t TotSum = sum_sizes<Enum::A, Enum::B, Enum::C>();
方法三:预处理器减少重复代码
当枚举和类数量较多时,用预处理器宏统一维护列表,自动生成映射和求和代码:
#include <cstddef> // 统一维护枚举与类的关联列表 #define ENUM_CLASS_PAIRS \ X(A) \ X(B) \ X(C) // 生成枚举类型 enum class Enum { First, #define X(name) name = First, ENUM_CLASS_PAIRS #undef X Last }; // 提前声明类(实际类定义可单独编写) #define X(name) class name; ENUM_CLASS_PAIRS #undef X class A { int x; }; class B { double y; char z; }; class C { long long w; }; // 自动生成枚举到类的映射模板 template<Enum E> struct EnumToType; #define X(name) template<> struct EnumToType<Enum::name> { using Type = name; }; ENUM_CLASS_PAIRS #undef X // 折叠表达式求和 template<Enum... Es> constexpr size_t sum_sizes() { return (sizeof(typename EnumToType<Es>::Type) + ...); } // 自动展开枚举列表求和 #define X(name) Enum::name, static constexpr size_t TotSum = sum_sizes<ENUM_CLASS_PAIRS>(); #undef X
以上所有方案均为编译期计算,TotSum的值会在编译阶段确定,运行期直接使用常量即可。
内容的提问来源于stack exchange,提问作者user14789259
相关产品推荐
相关产品推荐

