template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
在这种情况下,如何获取字段“m”的偏移量?我更喜欢使用 am 编译时表达式。
提前感谢您的帮助。此致
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
在这种情况下,如何获取字段“m”的偏移量?我更喜欢使用 am 编译时表达式。
提前感谢您的帮助。此致
@迈克尔·J
感谢您的回答。这并不是我想要的,但它给了我这样做的灵感:
template<class T, typename U>
std::ptrdiff_t member_offset(U T::* member)
{
return reinterpret_cast<std::ptrdiff_t>(
&(reinterpret_cast<T const volatile*>(NULL)->*member)
);
}
Sounds like you're looking for the offsetof() macro.
简单的答案是你不能。如果类型 U 是 POD,则可以使用宏offsetof
,但形式上,如果类型不是 POD,则它是未定义的行为:取决于编译器,您将收到编译时错误,或者只是一些错误的结果时间。而且您不能在指向成员的指针上使用它。您必须使用类的名称和成员的名称来调用它。
您可以获得偏移量,但它不是免费的:
template <typename T, class C>
size_t memberOffset(T C::*member)
{
C c {};
return size_t(&(c.*member)) - size_t(&c);
}
// usage
struct Vector {
int x;
int y;
};
size_t off = memberOffset(&Vector::y);
不幸的是,正如您所看到的,这不是 a constexpr
,因此它不能用于您可能想要的所有场景。它也有一个(非常小的)开销,但似乎编译器只是完全优化了它:https ://godbolt.org/z/jGeox9 。
如果您想知道是否可以constexpr
自己洒在任何地方并使其工作,您可以,并且您的编译器甚至可以编译并运行它,但是尽管许多编译器允许它存在已知缺陷,但使用强制转换size_t
在 a 中是无效的。constexpr
这种方法的功劳不属于我,但属于 Daniel Weiler 和这个优秀的要点:https ://gist.github.com/graphitemaster/494f21190bb2c63c5516