繁体   English   中英

指向成员的指针的偏移量

[英]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中使用constexprsize_t是无效的它。

这种方法的学分不属于我,而是属于 Daniel Weiler 和这个优秀的要点: https : //gist.github.com/graphitemaster/494f21190bb2c63c5516

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM