Ersatz fuer static object in einem cpp File
-
Sone schrieb:
typedef std::map<typename T ,std::string> enumToStr_t;ist das nicht ill-formed?
ist es, ebenso wie Zeile 33.
typename ist zwar an einigen Stellen erlaubt, an denen es nicht erforderlich wäre. Trotzdem erlaubt die Grammatiktypename-specifier:
typenamenested-name-specifier identifier
typenamenested-name-specifiertemplateopt simple-template-idweiterhin nicht einen einfachen Bezeichner an dieser Stelle.
-
Sone schrieb:
typedef std::map<typename T ,std::string> enumToStr_t;Ich verstehe natürlich den Trick, aber ist das nicht ill-formed? Oder hat mein GCC 4.8 noch nicht genug C++11-Unterstützung?
Hmm ja weiss jetzt auch ned so genau warum ich da gleich nochmal ein "typename" hingeschrieben hab. Dummerweise sagt mir da mein MSVC2010 nix dazu das, dass nicht erlaubt waere. Aber kennt man ja das der den Standard nicht immer so genau nimmt.
Aber jetz nochmal zu meinem Problem:
Und zwar hab ich das jetzt so geloest:
template<typename T, void(*initFunction)(std::map<T, std::string>& ) > struct enumHelper { //.... private: static enumToStr_t& map() { static enumToStr_t nameMap; if( nameMap.empty() ) { initFunction( nameMap ); } return nameMap; };Und dann in hash
//hash.h enum algo_t { sha_256, sha_512, whirlpool }; namespace detail { void initHashEnum(std::map<algo_t, std::string>& map); } typedef enumHelper<algo_t, &detail::initHashEnum> algo_enum; //hash.cpp namespace detail { void initHashEnum(std::map<algo_t, std::string>& map) { map[sha_256] = "SHA_256"; map[sha_512] = "SHA_512"; map[whirlpool] = "WHIRLPOOL"; } }Und sowmit kann ich jetzt ueber:
std::cout << algo_enum::toString( sha_256) << "\n"; // bzw std::string algo; std::cin >> algo; algo_t hashType = algo_enum::fromString( algo );meine Enums fuer die GUI besser aufbereiten.
Aber jetzt ist die Frage macht das Sinn und ist es einigermassen elegant oder hatte ihr schon mal das gleiche Problem und hab das um einiges besser geloest?
Gruessle
-
Gibt es einen vernünftigen Grund, nicht einfach ein array (sortiert aus pair<enum,const char*> oder einfach aus const char*, falls die Aufzählungskonstanten klein sind) zu verwenden? Die ganze Komplexität dynamischer Initialisierung wird vermieden, der Code wird erheblich kürzer und wahrscheinlich ist es auch noch schneller.
-
camper schrieb:
Gibt es einen vernünftigen Grund, nicht einfach ein array (sortiert aus pair<enum,const char*> oder einfach aus const char*, falls die Aufzählungskonstanten klein sind) zu verwenden? Die ganze Komplexität dynamischer Initialisierung wird vermieden, der Code wird erheblich kürzer und wahrscheinlich ist es auch noch schneller.
Muss ehrlich sagen ich steh grad aufn Schlauch. Soll ich dann statt der map ein const char* array nehmen oder statt meiner enumHelper class.
-
Sorry, mein Bruder war zu Besuch.
Mach niemals enum-helpers!
Oder wechsle nach Java/C#.In C++ reicht nötigenfalls zur lesbaren reinen Ausgabe für den ISO-Prüfer ein Array von C-Strings.
Siehe YAGNI
-
volkard schrieb:
Sorry, mein Bruder war zu Besuch.
Mach niemals enum-helpers!
Oder wechsle nach Java/C#.In C++ reicht nötigenfalls zur lesbaren reinen Ausgabe für den ISO-Prüfer ein Array von C-Strings.
Siehe YAGNI
Hmm naja mir gehts drum das ich den User einstellen lassen will was er zB. fuer einen Hash Algorithmus fuer HMAC verwenden will.
Es gibt jetz wie oben zu sehen ist zB. diese 3 Algorithmen: sha_256, sha_512, whirlpool.
Wie lassen ich jetzt dann am besten den User waehlen bzw lese die Settings aus einem config file (in json gehalten) wieder raus?Da brauch ich doch sowas wie toString(enumType) und fromString(enumType) oder seh ich das falsch?
-
Ne, es reicht wenn du in der Eingabe die Strings prüfst.
Du brauchst doch nicht beide Richtungen, oder? Also wieder ausgeben?
-
stuxn schrieb:
Da brauch ich doch sowas wie toString(enumType) und fromString(enumType) oder seh ich das falsch?
Ja!!!!!!!!!
Und warum machste das nicht? Warum willst Du das in einen Typ verkleiden? Warum willste neue Begriffe dafür erfinden, neue Klassen?Ich wierderhole:
stuxn schrieb:
Da brauch ich doch sowas wie toString(enumType) und fromString(enumType) oder seh ich das falsch?
Naja, fromstring(string), aber wir wußten, was gemeint war. Für komlpexere Lösungen verweise ich Dich an Sone. Der geht zur Zeit ab wie Schmidts Kätzchen und kann Dir alles sehr
komlpexidiomatisch darstellen.
-
Sone schrieb:
Ne, es reicht wenn du in der Eingabe die Strings prüfst.
Du brauchst doch nicht beide Richtungen, oder? Also wieder ausgeben?Ja doch eigentlich schon, da ich ja von meinen Settings Objekt in dem zB steht ich soll fuer HMAC sha_256 verwenden, in das config File ( ist im json Format) schreiben muss.
volkard schrieb:
stuxn schrieb:
Da brauch ich doch sowas wie toString(enumType) und fromString(enumType) oder seh ich das falsch?
Ja!!!!!!!!!
Und warum machste das nicht? Warum willst Du das in einen Typ verkleiden? Warum willste neue Begriffe dafür erfinden, neue Klassen?Ich wierderhole:
stuxn schrieb:
Da brauch ich doch sowas wie toString(enumType) und fromString(enumType) oder seh ich das falsch?
Naja, fromstring(string), aber wir wußten, was gemeint war. Für komlpexere Lösungen verweise ich Dich an Sone. Der geht zur Zeit ab wie Schmidts Kätzchen und kann Dir alles sehr
komlpexidiomatisch darstellen.Sollte das dann ca so ausschauen?
//hash.h namespace hash { enum algo_t { sha_256, sha_512, whirlpool }; const char* toString(algo_t algo); algo_t fromString(const std::string& algo); } //hash.cpp namespace hash { static std::pair<algo_t, const char*> hashNamePair[] = { std::make_pair(sha_256, "sha_256"),std::make_pair(sha_512, "sha_512"),std::make_pair(whirlpool, "whirlpool") }; const char* toString(algo_t algo) { auto r = std::find_if( std::begin( hashNamePair ), std::end( hashNamePair), [algo] (std::pair<algo_t, const char*>& value) { return value.first == algo; }); return r->second; } algo_t fromString(const std::string& algo) { auto r = std::find_if( std::begin( hashNamePair ), std::end( hashNamePair), [algo] (std::pair<algo_t, const char*>& value) { return value.second == algo; }); return r->first; } }Und das dann fuer jedes enum das ich dem User bereitstellen will?
-
stuxn schrieb:
Sollte das dann ca so ausschauen?
Jo, normalerweise schon. Ist recht schlicht, jeder Mitarbeiter vesteht es und es ist falls mehr Performace gebraucht wird, jederzeit unter Beibehalteng der Schnittstelle ausbaubar. Was will man mehr?
Konkretere Namen, ja.
-
volkard schrieb:
stuxn schrieb:
Sollte das dann ca so ausschauen?
Jo, normalerweise schon. Ist recht schlicht, jeder Mitarbeiter vesteht es und es ist falls mehr Performace gebraucht wird, jederzeit unter Beibehalteng der Schnittstelle ausbaubar. Was will man mehr?
Konkretere Namen, ja.
Hmm ja ok versteh ich schon ein bissle. Aber ich hab hier ca 5 Enums. Jetzt schreib ich fuer alle die 2 Funktionen. Nach einer weile faellt mir auf das es zu langsam ist wie du gesagt hast. Jetzt muss ich alle 10 Funktionen aendern. Genau sowas wollte ich halt mit meiner enumHelper class vermeiden.
-
stuxn schrieb:
Hmm ja ok versteh ich schon ein bissle. Aber ich hab hier ca 5 Enums.
Oh, 5. Mistige Arbeitgeber.
stuxn schrieb:
Jetzt schreib ich fuer alle die 2 Funktionen.
Null Problemo. Insbesondere dürfen sie ja sogar, wenn sie im Prinzip das selbe tun, eine andere Funkjtion aufrufen zum Beispiel.
stuxn schrieb:
Nach einer weile faellt mir auf das es zu langsam ist wie du gesagt hast. Jetzt muss ich alle 10 Funktionen aendern. Genau sowas wollte ich halt mit meiner enumHelper class vermeiden.
Das sehe ich nicht so. Und das siehst Du auch nicht, nachdem Du es hier ausgesprochen hast. Oder?