The issue is one of memory layout. The standard doesn't guarantee much about memory layout, in particular it doesn't guarantee that no offset exists between a derived and a base class...
For example:
class Foo: public boost::noncopyable
{
public:
virtual ~Foo();
};
Because boost::noncopyable
doesn't have a virtual
method, in gcc (void*)(Foo*)&f
and (void*)(boost::noncopyable*)&f
will have different values.
But this does not matter much in practice, because the compiler will perform the necessary adjustments. That is, if you only compare Foo*
you should be fine and dandy...
... Apart that multiple inheritance might break this, if there are several Foo
subobjects in your hierarchy.
On the other hand, you should be in one of two cases:
- either there is no hierarchy (no virtual) and then you can compare the address of objects as is
- or there is a hierarchy (and virtual method) and you use
dynamic_cast<void*>(&f)
to get the address of the complete object.
Therefore, as a template method, this would give:
template <typename T, typename U>
bool have_same_dynamic_location(T const& t, U const& u)
{
return dynamic_cast<void*>(&t) == dynamic_cast<void*>(&u);
}
(which is only valid if both T and U have virtual methods)