C++如何在编译期根据条件移除类成员字段以缩减类体积
问题根因
你原有方案无法压缩类大小的核心原因是C++标准要求所有完整对象的大小至少为1字节,即便你对Conditional做了空特化,作为类成员的空Conditional实例依然会占用至少1字节的空间,无法实现完全移除的效果。
C++20 无继承实现方案
你可以直接使用C++20引入的[[no_unique_address]]属性解决该问题,该属性允许空类型的成员与其他成员共享内存地址,完全不占用额外空间,无需用到类继承。
你原有Conditional模板的定义无需修改:
template <bool Condition, class FieldType> struct Conditional { FieldType Value; }; template <class FieldType> struct Conditional<false, FieldType> {};
只需要在声明Conditional类型的类成员时,加上[[no_unique_address]]标记即可:
struct TestClass { [[no_unique_address]] Conditional<true, int> int_field; // 条件成立时占用int大小 [[no_unique_address]] Conditional<false, double> double_field; // 条件不成立时完全不占空间 char common_field; // 普通公共成员 };
上述示例中,sizeof(TestClass)等于sizeof(int) + sizeof(char)对齐后的大小,double_field不会占用任何额外空间。
注意事项
如果你的类中存在多个条件不成立的Conditional成员,需要保证它们的类型不同才能全部被优化掉。你可以给模板增加一个Tag参数做区分:
// 增加非类型模板参数Tag区分不同字段 template <bool Condition, class FieldType, int Tag = 0> struct Conditional { FieldType Value; }; template <class FieldType, int Tag> struct Conditional<false, FieldType, Tag> {}; // 使用示例 struct MultiFieldClass { [[no_unique_address]] Conditional<false, int, 0> field1; [[no_unique_address]] Conditional<false, long, 1> field2; char c; }; // 此时sizeof(MultiFieldClass) == sizeof(char)
内容的提问来源于stack exchange,提问作者Erunehtar
相关产品推荐
相关产品推荐

