C++ Lambda-Ausdrücke für std::sort und std::lower_bound/equal_range auf ein struct-element in einen sortierten Vektor von structs
Ich habe einen std::vector von diesem struct:
struct MS
{
double aT;
double bT;
double cT;
};
was will ich mit std::sort auf aswell als std::lower_bound/equal_range etc...
Ich muss in der Lage sein, zu Sortieren und schauen Sie sich auf eines der ersten beiden Elemente des struct. Also im moment habe ich dieses:
class MSaTLess
{
public:
bool operator() (const MS &lhs, const MS &rhs) const
{
return TLess(lhs.aT, rhs.aT);
}
bool operator() (const MS &lhs, const double d) const
{
return TLess(lhs.aT, d);
}
bool operator() (const double d, const MS &rhs) const
{
return TLess(d, rhs.aT);
}
private:
bool TLess(const double& d1, const double& d2) const
{
return d1 < d2;
}
};
class MSbTLess
{
public:
bool operator() (const MS &lhs, const MS &rhs) const
{
return TLess(lhs.bT, rhs.bT);
}
bool operator() (const MS &lhs, const double d) const
{
return TLess(lhs.bT, d);
}
bool operator() (const double d, const MS &rhs) const
{
return TLess(d, rhs.bT);
}
private:
bool TLess(const double& d1, const double& d2) const
{
return d1 < d2;
}
};
Dies ermöglicht es mir, rufen sowohl std::sort und std::lower_bound mit MSaTLess() zu Sortieren/lookup basierend auf den im element und mit MSbTLess() zu Sortieren/lookup auf der Grundlage der bT-element.
Ich würde gerne Weg von der funktoren und mit C++0x-Lambda-Ausdrücke statt. Für die Art ist relativ einfach, da die lambda wird, nehmen Sie zwei Objekte des Typs MS als Argumente.
Was für die lower_bound-und anderen binary-search-lookup-algorithmen obwohl? Sie müssen in der Lage sein zu nennen, ein Komparator (MS -, Doppel -) Argumente und auch die Rückseite, (Doppel -, MS), richtig? Wie kann ich am besten diese mit einem lambda-Ausdruck in einem Aufruf von lower_bound? Ich weiß, ich könnte erstellen Sie eine MS dummy-Objekt mit den erforderlichen Schlüssel-Wert gesucht wird und verwenden dann die gleiche lambda als mit std::sort, aber gibt es einen Weg, es zu tun, ohne Verwendung von dummy-Objekten?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist ein wenig umständlich, aber wenn man sich mal die Definitionen von
lower_bound
undupper_bound
von der Norm ab, werden Sie sehen, dass die definition vonlower_bound
stellt der dereferenziert den iterator als ersten parameter der Vergleich (und der zweite Wert), in der Erwägung, dassupper_bound
setzt den iterator dereferenziert zweiten (und der Wert zuerst).So, ich noch nicht getestet, aber ich denke, Sie würde wollen:
und
Diese ist ziemlich böse, und ohne den Blick ein paar Dinge, die ich bin mir nicht sicher, du bist tatsächlich berechtigt, anzunehmen, dass die Implementierung verwendet der Komparator nur in der Art, wie es im text beschrieben - das ist eine definition das Ergebnis, nicht das Mittel, um dorthin zu gelangen. Es hilft auch nicht mit
binary_search
oderequal_range
.Es ist nicht ausdrücklich in 25.3.3.1, dass der iterator den Wert geben müssen, sein Cabrio zu T, aber es ist eine Art STILLSCHWEIGENDE durch die Tatsache, dass die Voraussetzung für den Algorithmus ist, dass T (in diesem Fall
double
) muss LessThanComparable, nicht, dass T müssen vergleichbar sein, um den Wert Art von iterator in einer bestimmten Reihenfolge.Also ich denke, dass es besser ist, sich einfach immer mit einem lambda (oder Funktor) vergleicht zwei MS-Strukturen, und statt der übergabe eines Doppel-als Wert übergeben Sie eine dummy-MS mit dem richtigen Feld auf den Wert, den du suchst:
Wenn Sie nicht möchten, dass MS einen Konstruktor (weil Sie es sein wollen-POD), dann schreiben Sie eine Funktion zum erstellen von MS-Objekt:
Wirklich, jetzt, es sind Lambda-Ausdrücke, die für diese Aufgabe wollen wir eine version der binären Suche, dauert ein unärer "Komparator":
C++0x nicht bieten, obwohl.
binary_search
benötigt einen Komparator, der funktioniert "in beide Richtungen", in der Erwägung, dass vielleichtlower_bound
nur erfordert es, um zu arbeiten, ein Weg. Wenn eslower_bound
aufgerufenbinary_search
, würde dies bedeuten, dasslower_bound
auch muss es in beide Richtungen funktionieren, aber mit der Abhängigkeit in die andere Richtung ist es zumindest noch plausibel.int
als der Wert, der gesucht werden soll, in einen container derchar
zusammen mit einer(int,int)
Komparator.Die algorithmen std::sort, std::lower_bound, und std::binary_search nehmen ein Prädikat, das vergleicht zwei Elemente des Containers. Jeder lambda-Ausdruck vergleicht zwei MS-Objekte und gibt
true
wenn Sie in Ordnung sind, sollte die Arbeit für alle drei algorithmen.Nicht direkt relevant, was du sagst über lambdas, aber das könnte eine Idee für die Nutzung des binary-search-Funktionen:
Grundsätzlich durch die Verwendung von
Find
als der Wert, haben wir nicht zu liefern, einen Komparator, weilFind
im Vergleich zuMS
mit dem Feld, die wir angeben. Dies ist die gleiche Art der Sache, wie die Antwort, Sie sahen mehr hier: wie zu Sortieren STL-Vektor, sondern mit dem Wert, anstatt den Komparator wie in diesem Fall. Nicht sicher, ob es wäre so toll zu bedienen, aber es könnte sein, denn es gibt den Wert zu suchen und die Suchbegriffe in das Feld in einem einzigen kurzen Ausdruck.Ich hatte das gleiche problem für
std::equal_range
und kam mit einer alternative Lösung.Habe ich eine Sammlung von Zeigern zu Objekten sortiert, auf einer Art Feld. Ich muss die finden, die Auswahl der Objekte für einen bestimmten Typ.
Obwohl es weniger effizient als ein spezielles Prädikat, wie es stellt eine unnötige nullptr test für jedes Objekt in meiner Sammlung, es stellt eine interessante alternative.
Nebenbei bemerkt, wenn ich benutze eine Klasse, wie in Ihrem Beispiel, Neige ich dazu das folgende zu tun. Sowie wird kürzer, dies ermöglicht es mir, fügen Sie zusätzliche Arten mit nur 1 Funktion pro Typ, dann eher 4-Betreiber pro Typ.
In der definition von lower_bound und andere STL-Algorithmen, die die Compare-Funktion ist derart, dass der erste Typ muss übereinstimmen, dass der Forward-Iterator und der zweite Typ müssen übereinstimmen, die von T (D. H., der Wert).
So dass man tatsächlich vergleichen können, die Dinge aus verschiedenen Objekten (tun, was die anderen Antwort genannt einen Einfachen Komparator). In C++11 :
Und dies kann verwendet werden, mit anderen STL-Algorithmus Funktionen.