Ich habe eine C++ - Klasse, für die ich einen Komparator definieren muss, der das Ergebnis mehrerer potenziell teurer Methoden berücksichtigen sollte. Ich möchte nicht das Ergebnis dieser Methoden für alle Objekte in meinem Set zwischenspeichern, weil die Kriterien mit der höchsten Priorität billiger sind, und ich erwarte, dass die sehr teuren unten nur in seltenen Fällen ausgelöst werden.C++ tiefer Lazy Vergleich mit eleganter Syntax?
Wenn ich eine cmp() -Funktion hatte, die -1, 0 oder 1 zurückgab, wenn das erste Argument kleiner, gleich oder größer als das zweite Argument ist, und mit logischen Verknüpfungen, die Ganzzahlen beibehalten, könnte ich leicht schreiben
int compare(const Class &rhs) const {
return cmp(expensive_method_a(), rhs.expensive_method_b()) ||
cmp(expensive_method_b(), rhs.expensive_method_b()) ||
...
}
Leider muss ich mit dem < Operator arbeiten, so wird es hässlich, teuer und fehleranfällig:
bool operator<(const Class &rhs) const {
return expensive_method_a() < rhs.expensive_method_a() ||
(expensive_method_a() == rhs.expensive_method_a() &&
(expensive_method_b() < rhs.expensive_method_b() ||
(expensive_method_b() == rhs.expensive_method_b() &&
(...
))))
}
oder alternativ weniger teuer, aber immer noch ziemlich hässlich:
Ich habe über std :: tie bei This andere Frage gelesen, aber wenn ich richtig verstehe, würde die Krawatte alle meine Methoden vor Beginn der Vergleiche bewerten, und ich möchte, dass diese Argumente faul ausgewertet werden.
Ich dachte über einen Präprozessormakro wie diese definieren:
#define CUT_COMPARE(a,b) { auto _x = (a); auto _y = (b); if (_x != _y) return (_x < _y); }
, die ich mag verwenden würde:
bool operator<(const Class &rhs) const {
CUT_COMPARE(expensive_method_a(), rhs.expensive_method_a());
CUT_COMPARE(expensive_method_b(), rhs.expensive_method_b());
...
}
der Hoffnung, dass die Streben meine _x
und _y
in einem privaten Rahmen würde einschließen, aber ach, clang++
klagt über mehrere Definitionen von _x
und _y
.
Gibt es einen schöneren Weg dazu?
Warum klagt clang? Ich habe den Code nicht getestet, aber die Variablen scheinen sich in separaten Bereichen zu befinden. –
Nur als eine Notiz, 'CUT_COMPARE' sollte eigentlich geschrieben werden: #define CUT_COMPARE (a, b) tue {....} while (0)' aus den hier gefundenen Gründen: http://stackoverflow.com/questions/ 1067226/c-multi-line-Makro-do-while0-vs-Bereich-Block –