Wir wechseln zu C++ 11, aber immer noch ein paar Monate entfernt. Bitte zögern Sie nicht, C++ 11 Antworten zu geben, aber wir sind neugierig, ob es eine nicht-hässliche Möglichkeit gibt, es in C++ 98/03 zu tun.Functor zum Anwenden einer willkürlichen Elementfunktion auf einen Container von Containern mit Objekten
Ein Mitarbeiter kam zu mir mit dem Code ähnelt:
typedef void(B::*fptr_t)();
void A::my_foreach(uint idx, fptr_t fptr) {
for(iter_type iter = asdf[idx].begin(); iter != asdf[idx].end(); ++iter)
iter->second->*fptr();
}
void A::get(uint idx) { my_foreach(idx, &B::get); }
void A::get(uint idx) { my_foreach(idx, &B::get); }
... zu fragen, ob es eine bessere Art und Weise war, auf die ich antwortete mit:
void A::get(uint idx) {
std::for_each(asdf[idx].begin()
, asdf[idx].end()
, boost::bind(&B::get, _1));
}
void A::put(uint idx) {
std::for_each(asdf[idx].begin()
, asdf[idx].end()
, boost::bind(&B::put, _1));
}
. .. aber das ließ mich immer noch fühlen, als könnte mehr getan werden, um Code-Duplikation zu vermeiden. Die allgemeinen Lösungen, die mir aufgetreten sind, sind:
- Re-Faktor der Code so die beteiligten Klassen weniger Verantwortung haben, und wickeln Sie den Behälter (n) in Dekorateur/Proxy-Objekte, die einen Teil der benötigten Funktionalität.
- Generisches
apply to my container
Elementfunktion, die die beabsichtigte Funktion als ein Argument annimmt (das heißt, Anrufer die Funktion bereitstellen muss) - Stellen zwei private Elementfunktionen: Die Funktion, die unter (2) und einer einen Funktors zurückzukehren es zu nennen , dann öffentliche Funktorobjekte, die im Konstruktor initialisiert wurden.
- Verwenden
boost::bind
die ganze Sache zu wickeln, einen Funktor machen, die wie folgt verwendet werden:
.
functor_t get = my_binder(&B::get);
functor_t put = my_binder(&B::put);
... wo my_binder
ein Objekt erzeugen würde, die die gleichen Operationen ausführen können, aber das hat sich rasch wegen hässlich wie ausgeführt werden viele Funktionen tatsächlich in dem obigen Code (operator[]
, X::begin
, X::end
, something for applying the function ptr to each element of the container
).
Gibt es einen anderen/besseren Weg vor C++ 11, oder sind diese Lösungen ziemlich viel verfügbar?
Sie können ersetzen 'boost :: bind (& B :: get, _1) 'mit' std :: mem_fun (& B :: get) ', und dann schreibe eine Funktion, die eine' std :: mem_fun_t ' –
Praetorian