Having previously been unaware of the existence of std::addressof
, why it exists makes sense to me: as a way of taking the an address in the presence of an over
It's actually quite simple when you think about it, to get the real adress of an object/function in precense of an overloaded operator&
you will need to treat the object as something other than what it really is, some type which cannot have an overloaded operator.. an intrinsic type (such as char
).
A char
has no alignment and can reside anywhere any other object can, with that said; casting an object to a reference to char is a very good start.
But what about the black magic involved when doing reinterpret_cast
?
In order to reinterpret the returned pointer from the implementation of addressof
we will eventually want to discard qualifiers such as const
and volatile
(to end up with a plain reference char
). These two can be added easily with reinterpret_cast
, but asking it to remove them is illegal.
T1 const a; reinterpret_cast (a);
/* error: reinterpret_cast from type ‘...’ to type ‘...’ casts away qualifiers */
It's a little bit of a "better safe than sorry" trick.. "Let us add them, just in case, we will remove them later."
Later we cast away the qualifiers (const and volatile) with const_cast
to end up with a plain reference to char
, this result is, as the final step, turned back into a pointer to whatever type we passed into our implementation.
A relevant question on this stage is why we didn't skip the use of reinterpret_cast
and went directly to the const_cast
? this too has a simple answer: const_cast
can add/remove qualifiers, but it cannot change the underlying type.
T1 a; const_cast (a);
/* error: invalid const_cast from type ‘T1*’ to type ‘T2*’ */
it might not be easy as pie, but it sure tastes good when you get it..