...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::hash
is written to be as portable as possible, but unfortunately, several
older compilers don't support argument dependent lookup (ADL) - the mechanism
used for customization. On those compilers custom overloads for hash_value
need to be declared in the boost namespace.
On a strictly standards compliant compiler, an overload defined in the
boost namespace won't be found when boost::hash
is instantiated,
so for these compilers the overload should only be declared in the same
namespace as the class.
Let's say we have a simple custom type:
namespace foo
{
struct custom_type
{
int value;
friend inline std::size_t hash_value(custom_type x)
{
boost::hash
<int> hasher;
return hasher(x.value);
}
};
}
On a compliant compiler, when hash_value
is called for this type,
it will look at the namespace inside the type and find hash_value
but on a compiler which doesn't support ADL hash_value
won't be found.
So on these compilers define a member function:
#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
friend inline std::size_t hash_value(custom_type x)
{
boost::hash
<int> hasher;
return hasher(x.value);
}
#else
std::size_t hash() const
{
boost::hash
<int> hasher;
return hasher(value);
}
#endif
which will be called from the boost
namespace:
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
{
std::size_t hash_value(foo::custom_type x)
{
return x.hash();
}
}
#endif
Full code for this example is at /libs/functional/hash/examples/portable.cpp.
On Visual C++ versions 6.5 and 7.0, hash_value
isn't overloaded for built in
arrays. boost::hash
, boost::hash_combine
and boost::hash_range
all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
boost::hash_value(long double)
on GCC on Solaris appears to treat
long double
s as doubles - so the hash function doesn't take into account the
full range of values.
Copyright © 2005 Daniel James |