Frage

Ich habe bei den Konstrukteuren von unordered_set suchen. Ist es nicht möglich, eine unordered_set mit einem benutzerdefinierten allocator Instanz ohne Angabe der Anzahl der Hash-Buckets zu konstruieren? Ich würde wirklich lieber nicht mit Zohan an Implementierungsdetails, weil ich eine benutzerdefinierte allocator will, und die Art bietet keine Definitionen für den Standardwert. MSDN gibt nur wie drei Überlastungen für den Konstruktor, von denen keine besonders nützlich sind.

Edit: Holy crap. Meine STL-Implementierung von std :: Hash nicht für Strings mit einem benutzerdefinierten allocator spezialisiert Typ- es nur die explizite typedefs std :: string tun kann, und std :: wstring. Ich meine, ich kann verstehen, nicht zu Hash-zufällige Zeichenfolge, um versuchen zu wollen, aber nur, weil es eine benutzerdefinierte allocator bekommt? Diese widert mich an.

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()));
    }
};

löst die Probleme, aber redundante Konstruktionen und kopieren? Ewwwww.

War es hilfreich?

Lösung

Das ist, seltsam, aber Sie haben recht. Ich nehme an, der Gedanke war, dass es viel des Guten, alle möglichen Parameter-Kombinationen zu unterstützen, mit Standardeinstellungen.

Der beste Weg, die ich denken kann, dies zu umgehen ist eine leere unordered_set mit allen Standardeinstellung zu konstruieren, erhalten den Standard-Bucket-Count von ihm unordered_set::bucket_count verwenden, und dann verwenden, als Eingabe, wenn Sie den Container instanziiert Sie eigentlich wollen.

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

Andere Tipps

Da Sie die Allocator schreiben, macht es Sinn, auch die Anzahl der Schaufeln zu steuern, schließlich sind beide Speicher bezogen werden:)

Steve das Herz der Methode gab, wenn Sie nicht wollen, lassen Sie mich jetzt schlagen eine Hilfsfunktion:)

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

Und damit ein wenig (einfach) Helfer:

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);
}

funktioniert recht gut mit auto:

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

Sie können natürlich auch einfach zerreißen die Konstante aus Ihrer Lieblings-Implementierung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top