Pregunta

He estado buscando en los constructores de unordered_set. ¿No es posible construir un unordered_set con una instancia de asignador de costumbre sin ajustar el número de recipientes de hash? Me gustaría mucho que se metan con los detalles de implementación porque quiero un asignador de costumbre, y el tipo proporciona ninguna definición para el valor por defecto. MSDN sólo da como tres sobrecargas para el constructor, ninguno de los cuales son terriblemente útil.

Edit: Mierda. Mi aplicación STL de std :: Hash no se especializará para cuerdas con un asignador de tipo personalizada que sólo puede hacer las typedefs explícitas std :: string y std :: wstring. Es decir, yo puedo entender que no quería tratar de cadenas de caracteres aleatorios de hash, pero sólo porque tiene un asignador de costumbre? Este me da asco.

tokens(std::unordered_set<string>().bucket_count(), std::hash<string>(), std::equal_to<string>(), stl_wrapper::hash_set<string>::allocator_type(this))
template<typename Char, typename CharTraits, typename Allocator> class std::hash<std::basic_string<Char, CharTraits, Allocator>>
    : public std::unary_function<std::basic_string<Char, CharTraits, Allocator>, std::size_t> {
public:
    size_t operator()(const std::basic_string<Char, CharTraits, Allocator>& ref) const {
        return std::hash<std::basic_string<Char, CharTraits>>()(std::basic_string<Char, CharTraits>(ref.begin(), ref.end()));
    }
};

resuelve los problemas, sino construcciones redundantes y copiar? Ewwwww.

¿Fue útil?

Solución

Eso es extraño, pero tienes razón. Supongo que la idea es que es una exageración para apoyar todas las posibles combinaciones de parámetros, con valores por defecto.

La mejor manera que puedo pensar de manejar esto es para construir una unordered_set vacío con todos los ajustes por defecto, obtener el recuento de cubo por defecto de ella usando unordered_set::bucket_count, y luego usar eso como entrada cuando se ejemplariza el contenedor que realmente desea.

unordered_set<int> temp;
size_t buckets = temp.bucket_count;
unordered_set<string> actual(buckets, Hash(), Pred(), 
    YourAllocator(param1 /*, etc */));

Otros consejos

Desde que está escribiendo la Allocator, tiene sentido para controlar el número de cubetas también, después de todo, ambos son relacionado con la memoria:)

Steve dio el corazón del método si no quiere, ahora permítanme proponer una función de ayuda:)

template <typename T>
size_t number_buckets()
{
  std::unordered_set<T> useless;
  return useless.bucket_count();
}

Y con esto, un poco (sencilla) helper:

template <typename T, typename Hash, typename Pred, typename Allocator>
std::unordered_set<T,Hash,Pred,Allocator>
  make_unordered_set(Hash const& hash, Pred const& pred, Allocator const& alloc)
{
  static size_t const nbBuckets = number_buckets<T>();
  return std::unordered_set<T,Hash,Pred,Allocator>(nbBuckets, hash, pred, alloc);
}

funciona bastante bien con auto:

auto set = make_unordered_set<std::string>(Hash(), Pred(), Allocator(1,2,3));

Se podría también, por supuesto, sólo tiene que rasgar la constante de su aplicación favorita.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top