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

在这种情况下,如何获取字段“m”的偏移量?我更喜欢使用 am 编译时表达式。

提前感谢您的帮助。此致

4

4 回答 4

6

@迈克尔·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)
    );
}
于 2011-04-11T06:38:28.690 回答
2

Sounds like you're looking for the offsetof() macro.

于 2011-04-11T06:18:27.910 回答
0

简单的答案是你不能。如果类型 U 是 POD,则可以使用宏offsetof,但形式上,如果类型不是 POD,则它是未定义的行为:取决于编译器,您将收到编译时错误,或者只是一些错误的结果时间。而且您不能在指向成员的指针上使用它。您必须使用类的名称和成员的名称来调用它。

于 2011-04-11T08:47:07.113 回答
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);

不幸的是,正如您所看到的,这不是 a constexpr,因此它不能用于您可能想要的所有场景。它也有一个(非常小的)开销,但似乎编译器只是完全优化了它:https ://godbolt.org/z/jGeox9 。

如果您想知道是否可以constexpr自己洒在任何地方并使其工作,您可以,并且您的编译器甚至可以编译并运行它,但是尽管许多编译器允许它存在已知缺陷,但使用强制转换size_t在 a 中是无效的。constexpr

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

于 2021-02-09T06:52:20.040 回答