C ++类型安全检测结构的偏移量

时间:2018-03-16 14:19:25

标签: c++

我正在尝试使用C ++语法来找出一种跟踪类中偏移量的通用方法,有点像offsetof,但是以类型安全的方式而且没有{ {1}}Š

我知道除了类型和常量之外,模板类可以使用 fields 进行模板参数化。所以我推出了这个原型:

#define

这段代码实际上可以打印字段偏移量,但我不确定我在这里做什么。实际上,在没有引用实例(#include <iostream> template <typename class_type, typename field_type> struct offsetter { offsetter(const char* name, field_type class_type::*field) : name(name) { fprintf(stderr, "%zu\n", field); } const char* const name; }; struct some_struct { float avg; int min; int max; struct internal { unsigned flag; int x; } test; char* name; }; int main() { offsetter<some_struct, float>("%h", &some_struct::avg); offsetter<some_struct, int>("%h", &some_struct::min); offsetter<some_struct, char*>("%h", &some_struct::name); offsetter<some_struct, some_struct::internal>("x", &some_struct::test); return 0; } )的情况下引用field是完全错误的。

但是它完成了工作:它打印了偏移量。我的猜测是,我遇到了一些漏洞,因为我不能指定foo.*field

我想我可能想要这样的东西:

size_t offset = field

然而,这不会&#39;工作,因为我不能采取xvalue的地址:

size_t offset = (&(std::declval<class_type>().*field) - &(std::declval<class_type>()))

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

AFAIK没有标准的做法。甚至标准offsetof也只针对标准布局类型定义。

你在做的是UB。您使用的是错误的说明符zu。你可以用成员指针做很多事情。你甚至不能在它们上做指针算术,你不能转换为char*也不能转换为整数类型。

此外,如果您的假设是成员指针只是一个整数,表示结构开头的偏移量是假的,不仅在理论上,而且在实践中。具有多重继承和虚拟继承确保了这一点。