[英]Offset of pointer to member
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)
);
}
听起来您正在寻找offsetof()宏。
简单的答案是你不能。 如果类型 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);
不幸的是,正如您所看到的,这不是constexpr
,因此它不能用于您可能想要的所有场景。 它也有(非常小的)开销,但编译器似乎只是完全优化了它: https : //godbolt.org/z/jGeox9 。
如果您想知道是否可以自己将constexpr
洒在各处并使其工作,您可以,并且您的编译器甚至可能编译并运行它,但是尽管许多编译器允许存在已知缺陷,但在constexpr
中使用constexpr
为size_t
是无效的它。
这种方法的学分不属于我,而是属于 Daniel Weiler 和这个优秀的要点: https : //gist.github.com/graphitemaster/494f21190bb2c63c5516
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.