Einfügen in eine unordered_set mit custom-hash-Funktion
Ich habe den folgenden code, um eine unordered_set<Interval>
. Dies stellt in Ordnung.
struct Interval {
unsigned int begin;
unsigned int end;
bool updated; //true if concat. initially false
int patternIndex; //pattern index. valid for single pattern
int proteinIndex; //protein index. for retrieving the pattern
};
struct Hash {
size_t operator()(const Interval &interval);
};
size_t Hash::operator()(const Interval &interval){
string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex);
return hash<string>()(temp);
}
unordered_set<Interval, string, Hash> test;
Aber ich kann nicht kompiliert wenn ich versuche, einfügen mit diesem code:
for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){
test.insert((*i));
}
Außerdem kann ich nicht feststellen, was das problem ist aus den Fehlermeldungen, zum Beispiel:
note: candidate is:
note: size_t Hash::operator()(const Interval&)
note: candidate expects 1 argument, 2 provided
Dachte ich, dass ich nur 1 argument...
Was ist das problem mit meinem code einfügen?
Hier ist die neue Instanziierung code: unordered_set<Interval, Hash> test;
Ich bin aber immer noch erhalten eine Reihe von Fehlermeldungen, zum Beispiel:
note: candidate is:
note: size_t Hash::operator()(const Interval&) <near match>
note: no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’
- stackoverflow.com/questions/17016175/...
- hast du auch gelesen, die Frage vor zu kommentieren, dass? Nein, du nicht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste problem:
Übergeben Sie
string
als zweites template-argument für Ihre Instanziierung derunordered_set<>
Klasse Vorlage. Das zweite argument sollte sein, die Art Ihres hasher Funktor, undstd::string
ist nicht ein callable-Objekt.Vielleicht gedacht zu schreiben:
Außerdem würde ich empfehlen, einen anderen Namen als
begin
undend
für Ihr (member) Variablen, da die Namen der algorithmen der C++ - Standard-Bibliothek.Zweite problem:
Sollten Sie im Hinterkopf behalten, dass die hasher Funktion qualifiziert werden sollten, als
const
, so dass Ihre functor sollten:Dritte problem:
Schließlich, wenn Sie wollen
std::unordered_set
in der Lage sein, um die Arbeit mit Objekten vom TypInterval
, müssen Sie definieren, ein Gleichheits-operator im Einklang mit Ihrer hash-Funktion. Standardmäßig wird, wenn Sie nicht angeben, eine Art argument als Dritter parameter derstd::unordered_set
Klasse Vorlageoperator ==
verwendet werden.Sie derzeit nicht über eine überlastung der
operator ==
für Ihre KlasseInterval
, so sollten Sie einen zur Verfügung stellen. Zum Beispiel:Fazit:
Nachdem alle oben genannten änderungen, können Sie Ihren code kompilieren in diesem live-Beispiel.
operator ==
imstruct
? Wie es ist, bekomme ich Fehler über mehrere Definitionen von==
. Wenn ich es erklären in einerstruct
in meiner header-Datei und definieren Sie es in meine .cpp-Datei (wie momentan arbeite ich für andere Betreiber), es gibt mir Fehler über und benötigt genau ein argument. Ex:bool IntervalEquality::operator==(const Interval&, const Interval&)’ must take exactly one argument
#include
ing es von mehreren.cpp
- Dateien). Verwenden Sie einfach dieinline
Schlüsselwort zu unterdrücken, dieses problem (als ich in meine aktualisierte Antwort).lhs
parameter, die implizit. Diethis
Zeiger beziehen sich auf die linke handInterval
Objekt.Interval
mitb == 12
unde == 3
produzieren den gleichen hash alsInterval
mitb == 1
unde == 23
.Ich denke, Andy Lauer, perfekt die Probleme gelöst mit Ihrem code. Allerdings würde ich hinzufügen die folgende member-Funktion, um Ihre
Interval
, die beschreibt, welche macht beiden Intervallen identisch:Bitte beachtet, dass ich auch gefolgt, Andy Lauer, Anregung und benannte die Mitglieder
begin
zub
undend
zue
. Als Nächstes definieren Sie ganz einfach den hash und Vergleich der Funktionen durch die Verwendung lambda-Ausdrücke. Als Ergebnis können Sie definieren Sie Ihreunordered_set
wie folgt:Schließlich, aus Gründen der Lesbarkeit habe ich konvertiert Ihre
for
Schleife in eine range-basiertefor
Schleife:Ausgabe (ich habe gerade gedruckt, die ersten drei Mitglieder jeder
Interval
):Wie Sie sehen können, gibt es nur zwei Intervalle gedruckt. Die Dritte (
{1, 2, true, 7, 4}
) wurde nicht eingefügt, umconcat
, weil seineb
,e
, undproteinIndex
gleich sind, dass der erste Intervall ({1, 2, false, 3, 4}
).Code auf Ideone