C++ 14 aggiunto is_transparent
supporto per ordini map
.
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);
}
};
ora ridefinire il proprio std::map
:
std::map<X, Details, ordering_helper> detailsMap;
e si è fatto. Ora puoi passare un Y const&
a detailsMap.find
o qualsiasi altra cosa.
Ora // TODO: compare lhs and rhs based off px and py
è un po 'fastidioso.
Ma dovrebbe essere scrivibile.
Se sono necessarie numerose classi diverse da confrontare con X
, è necessario avere una grande classe compare_helper
con ciascuna salvata oppure è necessario digitare l'operazione in qualche modo.
In sostanza, compare_helper
ha bisogno di memorizzare un puntatore-to-X
, o un std::function< int(X const&) >
che ti dice se il X
è inferiore, uguale o maggiore rispetto agli altri parametri. (noterai che questo non funziona quando confronti uno Y
o un contro uno contro uno Y
- in tal caso, restituendo false dovrebbe essere sicuro, poiché vedrai sempre uno solo non X
in una ricerca mappa specificata).
possiamo separare questo dalla definizione di compare_helper
con qualche ADL:
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;
}
};
ora l'utente finale deve semplicemente ignorare la funzione libera compare_with_X
nello spazio dei nomi del tipo che si desidera confrontare con X
a restituire un std::function<int(X const&)>
e la mappa sopra consente la ricerca dal tuo tipo non-X
.
Forse usare ['std :: find_if'] (http://en.cppreference.com/w/cpp/algorithm/find)? –
'std :: map>' –
La definizione della mappa non dovrebbe cambiare a destra? Tutto ciò che deve sapere è che voglio indicizzare per istanze X. Voglio semplicemente essere in grado di venire più tardi e dire "per favore usa questa istanza di Y per cercare, dato che ha tutto il necessario per abbinare una X" – nappyfalcon