I have the need to use offsetof
from a template
with a member selector. I've come up with a way, if you'll excuse the awkward syntax:
template <typename T,
typename R,
R T::*M
>
constexpr std::size_t offset_of()
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
Usage isn't perfect (annoying at best):
struct S
{
int x;
int y;
};
static_assert(offset_of<S, int, &S::x>() == 0, "");
static_assert(offset_of<S, int, &S::y>() == sizeof(int), "");
The non-constexpr
form is easier to use:
template <typename T, typename R>
std::size_t offset_of(R T::*M)
{
return reinterpret_cast<std::size_t>(&(((T*)0)->*M));
};
at the obvious disadvantage that it isn't done at compile-time (but easier to use):
int main()
{
std::cout << offset_of(&S::x) << std::endl;
std::cout << offset_of(&S::y) << std::endl;
}
What I'm looking for is syntax like the non-constexpr
variety, but still fully compile-time; however, I can't come up with the syntax for it. I would also be happy with an offset_of<&S::x>::value
(like the rest of the type traits), but can't figure out the syntax magic for it.
offsetof
? – Dismantlenullptr
(and I think->
counts as dereference) be UB already? But then again, VC's version of theoffsetof
macro isn't any different. So in practice it's probably rather implementation defined than undefined. – Osmanconstexpr
function isn't allowed to containreinterpret_cast
s or pointer derefs and address operators? – Osmanoffsetof
only works with member names, not with aM T::*
. – Wendel