<boost::hash
>написан так, чтобы быть максимально портативным, но, к сожалению, несколько старых компиляторов не поддерживают основанный на аргументах поиск (ADL) - механизм, используемый для настройки. На этих компиляторах пользовательские перегрузки для<hash_value
>должны быть объявлены в пространстве имен повышения.
На компиляторе, соответствующем строгим стандартам, перегрузка, определенная в пространстве имен бустера, не будет найдена, когда<boost::hash
>инстанцируется, поэтому для этих компиляторов перегрузка должна быть объявлена только в том же пространстве имен, что и класс.
Допустим, у нас есть простой пользовательский тип:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
friend std::size_t hash_value(custom_type x)
{
boost::hash
<int> hasher;
return hasher(x.value);
}
};
}
На совместимом компиляторе, когда<hash_value
>вызывается для этого типа, он будет смотреть на пространство имен внутри типа и находить<hash_value
>, но на компиляторе, который не поддерживает ADL<hash_value
>, не будет найден. Что еще хуже, некоторые компиляторы, которые поддерживают ADL, не найдут класс друзей, определенный внутри класса.
Итак, сначала выведите функцию члена из класса:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash(custom_type x)
{
boost::hash
<T> hasher;
return hasher(value);
}
};
template <class T>
inline std::size_t hash_value(custom_type<T> x)
{
return x.hash();
}
}
К сожалению, я не мог объявить хэш_значение другом, поскольку некоторые компиляторы не поддерживают друзей шаблона, поэтому вместо этого я объявил функцию участника для вычисления хэша и назвал ее из хэш_значения.
Для компиляторов, которые не поддерживают ADL, значение хэш_ должно быть определено в пространстве имен импульса:
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
Полный код для этого примера находится по адресу/libs/functional/hash/examples/portable.cpp.