- 只有外部类型才能知道内部成员子对象的偏移量
- 因此成员子对象类型需要知道外部类型
- 幸运的是,这种事情经常出现。事实上,它重复出现的频率可以被认为是……好奇。
- 不幸的是,没有人为它想出一个好名字。因此,它被称为奇怪重复模板模式或简称 CRTP。
困难的是找出一种方法让外部类型自动生成内部偏移量,而不必手动编写每个偏移量。手工操作很容易,但很乏味,例如。
// use an enum to create distinct types
template<typename Outer, typename Outer::FieldId ID>
struct Inner
{
static constexpr size_t offset();
};
struct Outer
{
enum FieldId { First, Second };
int header;
Inner<Outer, FieldId::First> first;
double interstitial;
Inner<Outer, FieldId::Second> second;
static constexpr size_t offset_of(std::integral_constant<FieldId, FieldId::First>) { return offsetof(Outer, first); }
static constexpr size_t offset_of(std::integral_constant<FieldId, FieldId::Second>) { return offsetof(Outer, second); }
};
template<typename Outer, typename Outer::FieldId ID>
constexpr size_t Inner<Outer, ID>::offset()
{
return Outer::offset_of(std::integral_constant<decltype(ID), ID> {});
}
这很笨拙,部分原因是std::integral_constant
包装器(可以避免或 typedef'd),但主要是因为 ID 到字段的映射必须在代码中手动表示。
如果没有编译时反射,自动化生产很难。如果您只在顶层使用类似元组的对象而不是结构,则可以自动化所有事情,但这使得交错“智能”和愚蠢的成员变得更加困难,并且可能会更改布局,而且它肯定会违反StandardLayoutType要求,这可能会阻止offsetof
完全工作。