Meine UTF-8 String Klasse
Verfasst: 21.04.2014, 14:38
Ich habe, wie vermutlich 99% aller Windows-Programmierer, das leidige Thema mit std::string und std::wstring :D
Nach diversen Nachforschungen bin ich auf den Trichter gekommen, dass es wohl am sinnvollsten ist, immer std::string zu verwenden und darin "einfach" UTF-8 zu speichern.
Bei API calls, die einen wstring oder wchar_t* brauchen, muss ich dann vor dem Aufruf konvertieren (und damit das alles auch funktioniert, beschränke ich mich bei der Kompatibilität mal auf C++11).
Folgende Klasse habe ich mir daher geschrieben:
Die Verwendung funktioniert wie folgt:
Vorteil ist, ich kann die Klasse überall ganz normal verwenden, inklusive aller bereits überladenen Operatoren.
Bei WINAPI calls nutze ich den operator(); den habe ich deshalb gewählt, weil er keine wichtige Funktionalität aus der std::string Klasse überdeckt und eine sehr hohe precedence hat, d.h. ich kann dann auch einfach wstring-methoden aufrufen, ohne mir einen abzubrechen oder mir einen Kopf darum zu machen (vgl. "s1().c_str()" mit "(*s1).c_str()", wenn ich operator* verwendet hätte, "*s1.c_str()" würde schiefgehen).
Da ich nur Standard-C++ verwende, denke ich sollte die Klasse auch unter Linux etc. laufen/compilieren, auch wenn sie dort nicht notwendig ist, weil ja alle API aufrufe den std::string als UTF-8 sehen.
Funktioniert für mich bisher sehr perfekt, ist ein Mini-Helfer der wunderbar alle meine Probleme löst. 8-)
Ich würde gerne wissen, ob ihr das für eine gute Idee haltet, oder ob ihr Probleme seht?
Eventuell habt ihr schonmal was ähnliches gebaut, oder habt Verbesserungsvorschläge?
Danke schonmal, Feedback aller Art würde mich freuen :)
Nach diversen Nachforschungen bin ich auf den Trichter gekommen, dass es wohl am sinnvollsten ist, immer std::string zu verwenden und darin "einfach" UTF-8 zu speichern.
Bei API calls, die einen wstring oder wchar_t* brauchen, muss ich dann vor dem Aufruf konvertieren (und damit das alles auch funktioniert, beschränke ich mich bei der Kompatibilität mal auf C++11).
Folgende Klasse habe ich mir daher geschrieben:
Code: Alles auswählen
class String : public ::std::string
{
public:
String() = default;
String(const std::string string)
{
this->assign(string);
}
String(const char* string)
{
this->assign(string);
}
String(const std::wstring string)
{
this->assign(std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(string));
}
String(const wchar_t* string)
{
this->assign(std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(string));
}
const std::wstring operator()() const
{
std::wstring ws = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().from_bytes(*this);
return ws;
}
};
Code: Alles auswählen
String s1(L"String aus wchar_t");
String s2("String aus char");
String neuerString = (String(L"wchar") + String("char")); //string operatoren funktionieren wie gewohnt
AufrufEinerEigenenFunktion(s1,s2);
AufrufEinerWinAPIFunktionMitWstr(s1());
AufrufEinerWinAPIFunktionDieLPCWSTRErwartet(st().c_str());
Bei WINAPI calls nutze ich den operator(); den habe ich deshalb gewählt, weil er keine wichtige Funktionalität aus der std::string Klasse überdeckt und eine sehr hohe precedence hat, d.h. ich kann dann auch einfach wstring-methoden aufrufen, ohne mir einen abzubrechen oder mir einen Kopf darum zu machen (vgl. "s1().c_str()" mit "(*s1).c_str()", wenn ich operator* verwendet hätte, "*s1.c_str()" würde schiefgehen).
Da ich nur Standard-C++ verwende, denke ich sollte die Klasse auch unter Linux etc. laufen/compilieren, auch wenn sie dort nicht notwendig ist, weil ja alle API aufrufe den std::string als UTF-8 sehen.
Funktioniert für mich bisher sehr perfekt, ist ein Mini-Helfer der wunderbar alle meine Probleme löst. 8-)
Ich würde gerne wissen, ob ihr das für eine gute Idee haltet, oder ob ihr Probleme seht?
Eventuell habt ihr schonmal was ähnliches gebaut, oder habt Verbesserungsvorschläge?
Danke schonmal, Feedback aller Art würde mich freuen :)