Macros
-
int Singleton::Register(SignaturEins function, SignaturZwei cFunction, const string& name) { if (Register(function, name) != -1) { Register(cFunction, name); return 0; } else { return -1; } }Im echten Beispiel sind "SignaturEins/Zwei" einfach typedefs für einen Funktionszeiger.
Ich hoffe du hast nichts dagegen das ich die Namen etwas generalisiert habe.
-
Das template könnte als Beispiel so aussehen:
template<SignaturEins T> int MyTemplate(int Zahl)
{
std::vector<int> tmp;
tmp.push_back(Zahl);
return T(tmp);
}
-
Compilieren sollte das Programm schon.
-
Ach, du willst ein kompilierbares minimalbeispiel? Sag das doch gleich :>
Warte 10 min, ich stells zusammen.
-
#include <vector> #include <string> #define REGISTER_MAKRO(function, name) \ Register(function, MyTemplate<function>, name) using namespace std; typedef int (*SigEins)(vector<int>); typedef int (*SigZwei)(int); template<SigEins T> int MyTemplate(int Zahl) { vector<int> tmp; tmp.push_back(Zahl); return T(tmp); } int Register(SigEins func, const string& name) { //hier gehts weiter zum registrieren in die eine Richtung, wies genau geht sollte irrelevant sein return 0; //wir gehen davon aus das das registrieren hier erfolgreich war //return -1; //das wird zurückgegeben falls es nicht erfolgreich war } int Register(SigZwei func, const string& name) { //hier gehts weiter zum registrieren in die andere Richtung, wies genau geht sollte irrelevant sein return 0; } int Register(SigEins function, SigZwei cFunction, const string& name) { if (Register(function, name) != -1) { Register(cFunction, name); return 0; } else { return -1; } } int Test(vector<int>) { return 2; } int main() { REGISTER_MAKRO(&Test, "test"); }
-
Noch gehts.
#include <vector> #include <string> using namespace std; typedef int (*SigEins)(vector<int>); typedef int (*SigZwei)(int); template<SigEins T> int MyTemplate(int Zahl) { vector<int> tmp; tmp.push_back(Zahl); return T(tmp); } int Register(SigEins func, const string& name) { //hier gehts weiter zum registrieren in die eine Richtung, wies genau geht sollte irrelevant sein return 0; //wir gehen davon aus das das registrieren hier erfolgreich war //return -1; //das wird zurückgegeben falls es nicht erfolgreich war } int Register(SigZwei func, const string& name) { //hier gehts weiter zum registrieren in die andere Richtung, wies genau geht sollte irrelevant sein return 0; } int Register(SigEins function, SigZwei cFunction, const string& name) { if (Register(function, name) != -1) { Register(cFunction, name); return 0; } else { return -1; } } int Test(vector<int>) { return 2; } #define REGISTER_MAKRO(function, name) \ Register(function, MyTemplate<function>, name) //alles oberhalb unveränder, außer das makro runtergezogen zum besser //anschauen können, während ich das template zusammenfrickle. template<SigEins FUNC> void REGISTER_TEMPLATE(const string& name){ Register(FUNC,MyTemplate<FUNC>,name); } int main() { REGISTER_MAKRO(&Test, "test"); REGISTER_TEMPLATE<&Test>("test"); }Wenn die function auch andere Signaturen als SigEins haben können soll, wird der Aufruf in der main aber schon häßlicher. Da mache ich mich dann aber auch locker und denke an Makros.
Aber spaßig wird's mit
#define REGISTER_MAKRO2(function) \ Register(function, MyTemplate<function>, #function) int main() { REGISTER_MAKRO(&Test, "test"); REGISTER_TEMPLATE<&Test>("test"); REGISTER_MAKRO2(Test); }
-
Stimmt, hast mich überzeugt, geht.
Ich finde zwar immer noch die Verwendung des Makros sieht schöner aus (da es ähnlicher an dem Funktionsaufruf ist den es eigentlich darstellt), aber wegen den üblichen Problemen mit Makros sollte man es evtl lassen. Die ganze Verwendung in einem Projekt nur wegen sowas zu ändern würde ich allerdings nicht :>
-
Janjan schrieb:
Makros sind in C++ nur für Include-Guards und bedingte Kompilation gut.
Nicht ganz. Alleine schon wenn man an Dinge wie
assertoderBOOST_FOREACHdenkt.Es gibt auch sonst ab und zu Situationen, in denen Makros sehr praktisch sind. Nur weil man etwas viel hässlicher ohne sie erledigen kann, ist das kein Grund, auf sie zu verzichten. Ihre Einsatzgebiete reichen von einfachen Textersetzungen bis zu mächtigen Codegeneratoren. Die Möglichkeiten sollte man nicht leichtfertig unterschätzen.
Davon abgesehen war es noch nie vorteilhaft, Sprachmittel aus C kategorisch schlecht zu finden.