简体   繁体   English

指向成员的指针的偏移量

[英]Offset of pointer to member

template<class T, typename U> ptrdiff_t foo(T U::* m)
{
    // return offset
}

How I can get the offset of the field 'm' in this context?在这种情况下,我如何获得字段“m”的偏移量? I would prefer to use am compile-time expression.我更喜欢使用 am 编译时表达式。

Thanks in advance for any help.在此先感谢您的帮助。 Best regards此致

@Michael J @迈克尔J

Thanks for your answer.感谢您的回答。 This wasn't exactly what I was looking for, but it gives me the inspiration to doing that:这并不是我一直在寻找的,但它给了我这样做的灵感:

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()宏。

The simple answer is that you can't.简单的答案是你不能。 If the type U is a POD, you can use the macro offsetof , but formally, it's undefined behavior if the type isn't a POD: depending on the compiler, you'll get a compile time error, or simply wrong results some of the time.如果类型 U 是 POD,您可以使用宏offsetof ,但正式地说,如果类型不是 POD,则它是未定义的行为:取决于编译器,您将收到编译时错误,或者只是错误的结果时间。 And you can't use it on a pointer to member.并且您不能在指向成员的指针上使用它。 You have to invoke it with the name of the class, and the name of the member.您必须使用类名和成员名来调用它。

You can get the offset, but it's not free:可以得到弥补,但它不是免费的:

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);

Unfortunately as you can see, this is not a constexpr , and so it can't be used in all scenarios you may want to.不幸的是,正如您所看到的,这不是constexpr ,因此它不能用于您可能想要的所有场景。 It also has a (very small) overhead, but it seems that the compiler just completely optimizes it out: https://godbolt.org/z/jGeox9 .它也有(非常小的)开销,但编译器似乎只是完全优化了它: https : //godbolt.org/z/jGeox9

If you are wondering if you can just sprinkle constexpr everywhere yourself and make this work, you can, and your compiler might even compile it and run, but using a cast to size_t is not valid in a constexpr despite the known defect that many compilers allow it.如果您想知道是否可以自己将constexpr洒在各处并使其工作,您可以,并且您的编译器甚至可能编译并运行它,但是尽管许多编译器允许存在已知缺陷,但在constexpr中使用constexprsize_t是无效的它。

Credits for this method do not belong to me, but to Daniel Weiler and this excellent gist: https://gist.github.com/graphitemaster/494f21190bb2c63c5516这种方法的学分不属于我,而是属于 Daniel Weiler 和这个优秀的要点: https : //gist.github.com/graphitemaster/494f21190bb2c63c5516

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

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