<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.