Re: casting (void *) to (class *)
On Apr 15, 5:00 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
On Apr 15, 12:58 pm, "Alf P. Steinbach" <al...@start.no> wrote:
* James Kanze:
On Apr 15, 4:04 am, "Alf P. Steinbach" <al...@start.no> wrote:
* Jonathan Lee:
But better, don't use void* pointers (except for the
special case of identifying objects in e.g. a hash table,
in which case you should make sure to have pointers to
complete objects, e.g. obtained by dynamic_cast to
void*).
I'm not sure I understand this one. Do you mean just using the
pointer as the key?
Yes.
(And how do you get a hash value for a pointer, portably?)
Wait a sec, checking Boost...
KO.
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const& v)
#else
template <class T> std::size_t hash_value(T* v)
#endif
{
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
}
Wow! Why can't it be as simple as:
std::size_t x = v - static_cast<T*>(0);
?
Because the subtraction isn't defined. On the other hand, it
could be as simple as:
std::size_t x = reinterpret_cast< std::size_t >( v ) ;
I don't see what the extra cast changes. Of course, neither
that nor the original work portably. In fact, they're not even
guaranteed to compile, and if they do, they may result in two
pointers which compare equal having different hash values.
Your suggestion contains undefined behavior, but on the whole,
is probably more robust than the original code in practice. I
can see it giving the same value for all dynamically allocated
objects on some systems, but I can't imagine a real case where
it would give different hash values to pointers which compare
equal.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34