我以前使用它来根据传入成员对象指针来提取对象成员的 size_t 偏移量。
template <typename T, typename U>
constexpr size_t memberOffset(U T::*member)
{
return (char*)&((T*)nullptr->*member) - (char*)nullptr;
}
struct Point{float x,y,z; };
memberOffset(&Point::y) == 4;
我使用它作为反射库的一部分来散列两种类型以实现兼容性。IE
struct Point{ float x,y,z;};
struct Point3d{float x,y,z;};
出于序列化目的,上述两者是相同的,因此使用 x,y,z 类型的附加元数据和成员名称,我可以为这两种类型生成哈希并检查兼容性。
在 gcc 9 中,由于 constexpr 函数中的 UB,memberOffset 函数现在被破坏了。我正在寻找不调用 UB 或 gcc 9 解决方法的 constexpr 版本。__builtin__offsetof 不采用相同的语法,因此与我已经开发的内容不兼容。
[编辑]
为了增加清晰度,这被用作我编写的元编程库的扩展的一部分。大部分代码与使用成员对象指针等为结构生成序列化和绑定代码有关。因此,该库通常按如下方式使用:
template<>
struct MetaData<Point3d>{
auto getMember(integral_constant<0>){ return makeMemberObjectPointer("x", &Point3d::x); }
auto getMember(integral_constant<1>){ return makeMemberObjectPointer("y", &Point3d::y); }
auto getMember(integral_constant<2>){ return makeMemberObjectPointer("z", &Point3d::z); }
};
由于代码已经在任何地方都使用了成员对象指针,我希望能够使用现有的内容来提取偏移量,而不是必须通过额外调用 offsetof 来更新每个调用点。