我正在尝试使用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>()))
有没有办法做到这一点?
答案 0 :(得分:1)
AFAIK没有标准的做法。甚至标准offsetof
也只针对标准布局类型定义。
你在做的是UB。您使用的是错误的说明符zu
。你可以用成员指针做很多事情。你甚至不能在它们上做指针算术,你不能转换为char*
也不能转换为整数类型。
此外,如果您的假设是成员指针只是一个整数,表示结构开头的偏移量是假的,不仅在理论上,而且在实践中。具有多重继承和虚拟继承确保了这一点。