template<class T, typename U> ptrdiff_t foo(T U::* m) { // return offset }
在这个上下文中,我如何获得字段“m”的偏移量?我更喜欢使用am编译时表达式。提前感谢任何帮助。最好的问候
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) ); }
8tntrjer2#
听起来你在找offsetof()宏。
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
constexpr
size_t
4uqofj5v4#
简单的答案是你不能。如果类型U是POD,你可以使用宏offsetof,但形式上,如果类型不是POD,它是未定义的行为:根据编译器的不同,你可能会得到一个编译时错误,或者有时只是错误的结果。而且不能在指向成员的指针上使用。你必须用类名和成员名来调用它。
offsetof
4条答案
按热度按时间4si2a6ki1#
@Michael J
谢谢你的回答。这并不是我想要的,但它给了我这样做的灵感:
8tntrjer2#
听起来你在找offsetof()宏。
moiiocjp3#
你 * 可以 * 获取偏移量,但它不是免费的:
不幸的是,正如您所看到的,这不是一个
constexpr
,因此它不能在您想要的所有场景中使用。它也有(非常小的)开销,但似乎编译器只是完全优化了它:https://godbolt.org/z/jGeox9。如果你想知道你是否可以自己把
constexpr
洒到每个地方并使其工作,你可以,你的编译器甚至可以编译它并运行,但是在constexpr
中使用size_t
的强制转换是无效的,尽管许多编译器允许它。这种方法的功劳不属于我,而是属于戴尔·维勒和这个优秀的要点:https://gist.github.com/graphitemaster/494f21190bb2c63c5516
4uqofj5v4#
简单的答案是你不能。如果类型U是POD,你可以使用宏
offsetof
,但形式上,如果类型不是POD,它是未定义的行为:根据编译器的不同,你可能会得到一个编译时错误,或者有时只是错误的结果。而且不能在指向成员的指针上使用。你必须用类名和成员名来调用它。