template<class T, typename U> ptrdiff_t foo(T U::* m)
{
// return offset
}
如何在此上下文中获取字段'm'的偏移量?我更喜欢使用am编译时表达式。
提前感谢您的帮助。最好的问候
答案 0 :(得分:5)
@Michael 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)
);
}
答案 1 :(得分:3)
听起来你正在寻找offsetof()宏。
答案 2 :(得分:0)
简单的答案是,你做不到。如果U型是POD,
你可以使用宏offsetof
,但正式来说,它是未定义的
行为如果类型不是POD:取决于编译器,
你会得到一个编译时错误,或者只是错误的结果
时间。而且你不能在指向成员的指针上使用它。您
必须使用类的名称和名称来调用它
会员。
答案 3 :(得分:0)
您可以获得偏移量,但它不是免费的:
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
洒在各处并使其工作,您可以,并且您的编译器甚至可能编译并运行它,但是使用强制转换为 size_t
是无效的尽管存在许多编译器允许的已知缺陷,但在 constexpr
中。
此方法的功劳不属于我,而是属于 Daniel Weiler 和这个出色的要点:https://gist.github.com/graphitemaster/494f21190bb2c63c5516