C++ 14 hinzugefügt is_transparent
Unterstützung zu map
Ordnungen.
struct compare_helper {
X const* px = nullptr;
Y const* py = nullptr;
compare_helper(compare_helper&&)=default;
compare_helper(X const& x):px(&x) {}
compare_helper(Y const& y):py(&y) {}
explicit operator bool()const{return px&&py;}
friend bool operator<(compare_helper&& lhs, compare_helper&& rhs) {
if (!lhs || !rhs) {
return !rhs < !lhs;
}
// TODO: compare lhs and rhs based off px and py
}
};
struct ordering_helper {
using is_transparent=std::true_type;
bool operator()(compare_helper lhs, compare_helper rhs)const{
return std::move(lhs)<std::move(rhs);
}
};
jetzt neu definieren Ihre std::map
:
std::map<X, Details, ordering_helper> detailsMap;
und Sie sind fertig. Sie können jetzt eine Y const&
an detailsMap.find
oder was auch immer übergeben.
Jetzt ist // TODO: compare lhs and rhs based off px and py
ein bisschen nervig.
Aber es sollte beschreibbar sein.
Wenn Sie viele verschiedene Klassen benötigen, um mit X
vergleichen zu können, und Sie entweder eine große compare_helper
Klasse mit jedem gespeicherten benötigen, oder Sie müssen die Operation irgendwie tippen-löschen.
Grundsätzlich compare_helper
Bedürfnisse speichern einen Zeiger-to-X
oder ein std::function< int(X const&) >
, die Sie sagt, wenn die X
kleiner als, gleich oder größer als die anderen Parameter. (Sie werden feststellen, dass dies fehlschlägt, wenn Sie eine Y
mit einer Y
oder einer Z
mit einer Y
vergleichen. In diesem Fall sollte die Rückgabe von false sicher sein, da Sie in einer Kartensuche immer nur eine Nicht-X
sehen.
Wir können dies aus der Definition von compare_helper
mit einigen ADL entkoppeln:
struct compare_helper {
X const* px = nullptr;
using f_helper = std::function< int(X const&) >;
f_helper not_X;
compare_helper(compare_helper&&)=default;
compare_helper(X const& x):px(std::addressof(x)) {}
template<class NotX,
class=std::enable_if_t< std::is_convertible<
decltype(compare_with_X(std::forward<NotX>(notx)))
, f_helper
>{}
>
compare_helper(NotX&& notx):
not_X(compare_with_X(std::forward<NotX>(notx)))
{}
explicit operator bool()const{return px&¬_X;}
friend bool operator<(compare_helper&& lhs, compare_helper&& rhs) {
if (!lhs || !rhs) {
return !rhs < !lhs;
}
if (lhs.px && rhs.px) { return *lhs.px < *rhs.px; }
if (lhs.px && rhs.not_X) { return rhs.not_X(*lhs.px) < 0; }
if (lhs.not_X && rhs.px) { return lhs.not_X(*rhs.px) > 0; }
else return false;
}
};
jetzt der Endbenutzer einfach hat die freie Funktion compare_with_X
im Namensraum des Typs außer Kraft setzen Sie mit X
vergleichen wollen geben Sie eine std::function<int(X const&)>
zurück, und die obige Karte ermöglicht das Suchen von Ihrem Typ X
.
Vielleicht verwenden Sie ['std :: find_if'] (http://en.cppreference.com/w/cpp/algorithm/find)? –
'std :: map>' –
Die Kartendefinition sollte nicht richtig ändern? Alles, was es wissen muss, ist, dass ich nach X-Instanzen indexieren möchte. Ich möchte einfach später kommen und sagen "Bitte benutzen Sie diese Y-Instanz, um zu suchen, da es alles hat, was Sie brauchen, um ein X zu finden" – nappyfalcon