c++ 指向成员的指针的偏移量

ijnw1ujt  于 2023-06-25  发布在  其他
关注(0)|答案(4)|浏览(93)
template<class T, typename U> ptrdiff_t foo(T U::* m)
{
    // return offset
}

在这个上下文中,我如何获得字段“m”的偏移量?我更喜欢使用am编译时表达式。
提前感谢任何帮助。最好的问候

4si2a6ki

4si2a6ki1#

@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)
    );
}
moiiocjp

moiiocjp3#

你 * 可以 * 获取偏移量,但它不是免费的:

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中使用size_t的强制转换是无效的,尽管许多编译器允许它。
这种方法的功劳不属于我,而是属于戴尔·维勒和这个优秀的要点:https://gist.github.com/graphitemaster/494f21190bb2c63c5516

4uqofj5v

4uqofj5v4#

简单的答案是你不能。如果类型U是POD,你可以使用宏offsetof,但形式上,如果类型不是POD,它是未定义的行为:根据编译器的不同,你可能会得到一个编译时错误,或者有时只是错误的结果。而且不能在指向成员的指针上使用。你必须用类名和成员名来调用它。

相关问题