从类型与偏移量获取成员指针:offsetof的逆实现可行吗?
从偏移量获取C++类成员指针的实现方法
已知offsetof(type, member)可返回type类型内存起始位置到member成员的字节偏移量,但C++标准并未提供对应的逆操作——即从类型与偏移量得到成员指针的memberof(type, offset)。以下是满足不滥用语言特性、跨平台、支持constexpr要求的实现方案:
核心原理
对于类的非虚成员,成员指针(如var_type_t my_type_t::*)在主流编译器的底层实现中,直接存储成员的字节偏移量(虽未被C标准强制规定,但该实现符合标准对成员指针的操作语义,跨平台兼容性良好)。我们可通过合法的类型转换,将偏移量转换为对应的成员指针,同时利用C17及以后的constexpr特性实现编译期计算。
实现代码
#include <cstddef> template <typename Class, typename Member> constexpr Member Class::* memberof(size_t offset) noexcept { // C++17允许constexpr环境下,将整数转换为标准布局类型的非虚成员指针 return reinterpret_cast<Member Class::*>(offset); }
使用示例
结合你给出的结构体:
struct my_type_t { var_type_t m_var; }; // 通过offsetof获取成员偏移量 constexpr size_t offset = offsetof(my_type_t, m_var); // 使用memberof转换为成员指针 constexpr var_type_t my_type_t::* ptr_to_var_member = memberof<my_type_t, var_type_t>(offset);
关键注意事项
- 仅支持非虚成员:虚成员的指针底层包含虚表相关信息,无法通过单纯偏移量转换得到,此方法不适用。
- 标准布局类型要求:确保
Class是标准布局类型,这样成员偏移计算与指针转换的语义完全符合标准,跨平台兼容性更可靠。 - 偏移量有效性:传入的偏移量必须是
Class中某个Member类型成员的合法偏移,否则行为未定义。 - C++版本限制:constexpr特性需要C++17及以上版本支持;若使用更早版本,可移除constexpr关键字,仍能保证运行期的正确性。
内容的提问来源于stack exchange,提问作者gg99
相关产品推荐
相关产品推荐

