Wie sollte ein gutes Stringframework aussehen?
-
Inspiriert von eimem anderen Thread stellt sich mir die Frage, wie ein gutes C++ Stringframework aussehen sollte. Was sollte es alles können (Verschiedene Codierungen(Unicode, UTF8...), Transformation(toUpper...) ,Konvertierung Zahl<->String, Suchen, Ersetzen, Regex... ) und wo sollen die Methoden/Funktionen hin? Wie soll es intern die Daten speichern?...
-
-
@string: Java hat interessante Aspekte, doch die Form wie Frameworks unter Java und unter C++ sinnvoll sind unterscheidet sich.
Dickebeine schrieb:
Inspiriert von eimem anderen Thread stellt sich mir die Frage, wie ein gutes C++ Stringframework aussehen sollte. Was sollte es alles können (Verschiedene Codierungen(Unicode, UTF8...), Transformation(toUpper...) ,Konvertierung Zahl<->String, Suchen, Ersetzen, Regex... ) und wo sollen die Methoden/Funktionen hin? Wie soll es intern die Daten speichern?...
1. Die Klasse sollte nicht mit Methoden überladen werden, die keine Stringinterna benötigen (Dafür sind freie Funktionen besser)
2. Sie sollte vom restlichen Framework nahtlos unterstützt werden (Dies ist ein Faktor der zumindestens für sd::string wohl ab C++09 endlich erfüllt sein wird).
3. Es sollte eine gute Unicodeunterstützung geben (Auch dies muss nicht zwangsweise in der stringklasse liegen)Zu der internen Speicherung bin ich nicht so fixiert, von mir aus auch weiterhin mit Templates, wichtig ist aber das Aspekt 3 beachtet wird.
4. Alles weitere wie Konvertierungen etc. lässt sich durch Funktionen oder andere Klassen besser lösen, als durch überfüllung der Klasse. (In die Klasse gehören imho nur solche Methoden, die Stringinterna benötigen). Was ich wichtig fände wären aber sprechende Funktions und Methodennamen. Im anderen Thread hatte ich schon erwähnt das ich lexical_cast mag, eine Funktion wie convertTo<Type>(...) aber sprechender wäre.
Auch über das Thema mutable lass ich mich hier jetzt nicht aus.
cu André
-
sucht euch was aus: http://www.and.org/vstr/comparison
-
Am liebsten würde ich wählen können, was die Klasse mir bietet. Wichtig ist, dass ich das gleiche Interface haben will, wenn ich nur einen C-String wrappe oder eine Multibyte unterstützende Stringklasse mit eigener Speicherverwaltung habe. Eigentlich ging Boost.Range ein bisschen in die Richtung, auch wenn die es leider in 1.34 kaputt gemacht haben :(.
string schrieb:
so: http://java.sun.com/javase/6/docs/api/java/lang/String.html
Wenn es um ein Framework für C++ geht, dann sollte es wohl eher heißen "so genau nicht".
-
rüdiger schrieb:
string schrieb:
so: http://java.sun.com/javase/6/docs/api/java/lang/String.html
Wenn es um ein Framework für C++ geht, dann sollte es wohl eher heißen "so genau nicht".
Wieso?
asc schrieb:
1. Die Klasse sollte nicht mit Methoden überladen werden, die keine Stringinterna benötigen (Dafür sind freie Funktionen besser)
Kann man sich jetzt streiten, finde aber die String-Klasse nicht ueberladen.
asc schrieb:
2. Sie sollte vom restlichen Framework nahtlos unterstützt werden (Dies ist ein Faktor der zumindestens für sd::string wohl ab C++09 endlich erfüllt sein wird).
Also das erfuellt die String-Klasse wohl 100%.
asc schrieb:
3. Es sollte eine gute Unicodeunterstützung geben (Auch dies muss nicht zwangsweise in der stringklasse liegen)
Dies ebenfalls.
asc schrieb:
4. Alles weitere wie Konvertierungen etc. lässt sich durch Funktionen oder andere Klassen besser lösen, als durch überfüllung der Klasse.
Die Konvertierungs-Methoden sind Klassenmethoden, sind also ausserhalb des Objektes. In Java geht das halt nicht anders, in C++ waehren das freie Funktionen.
-
DEvent schrieb:
Wieso?
weil das java ist. und in java programmiert man java und in c++ c++.
und das interface von String ist überladen da Java einem technisch kaum eine andere Möglichkeit lässt.
dazu fehlt eben etwas wie char_traits oder vergleichbare funktionalität.
String ist ok für java, aber in c++ würde man da so ziemlich alles anders machen.
-
Shade Of Mine schrieb:
String ist ok für java, aber in c++ würde man da so ziemlich alles anders machen.
Mag das evtl mal jemand konkreter ausführen?
-
Badestrand schrieb:
Shade Of Mine schrieb:
String ist ok für java, aber in c++ würde man da so ziemlich alles anders machen.
Mag das evtl mal jemand konkreter ausführen?
char_traits, die frage ob string wirklich immutable sein sollte im c++ kontext, dazu etwas generative programmierung und ein komplett anderes interface - nämlich keine regex innerhalb der string klasse, und die meisten methoden sind mit stl algos super implementierbar. dazu fehlen dann eben noch iteratoren und die convertTo methoden sind in boost::lexical_cast deutlich besser aufgehoben.
-
DEvent schrieb:
Wieso?
Also mein einziges Argument dafür alles wie in Java in eine Klasse zu stopfen wäre das dann die Objektsyntax möglich ist. Ja, ich mag OOP, aber in C++ als Multiparadigmensprache zieht sind andere Vorgehensweisen optimal.
Leider komme ich erst ab den 18. wieder an meine Bücher, sonst würde ich hierzu mal schauen in welcher Quelle (war entweder Herb Sutter oder Scott Meyer) hierzu einen sehr guten Artikel geschrieben hat (Wann sollte man Funktionen, wann Methoden etc. verwenden).
cu André
-
asc schrieb:
Also mein einziges Argument dafür alles wie in Java in eine Klasse zu stopfen wäre das dann die Objektsyntax möglich ist. Ja, ich mag OOP, aber in C++ als Multiparadigmensprache zieht sind andere Vorgehensweisen optimal.
a.b(c) ist kein bisschen mehr oder weniger oop als b(a,c) oder b.a(c) oder ähnliches.
(Wann sollte man Funktionen, wann Methoden etc. verwenden).
funktion wenn es geht, methoden wenn es sein muss.
-
Badestrand schrieb:
Shade Of Mine schrieb:
String ist ok für java, aber in c++ würde man da so ziemlich alles anders machen.
Mag das evtl mal jemand konkreter ausführen?
Weil in C++ die streams dafür da sind, die ganzen konvertierungen durchzuführen. Die streams verwalten die locales und locales braucht man um anständig Formatierungen durchzuführen. In Java sieht man bereits das Problem, da ist es nämlich nicht wirklich einfach, zahlenformate umzudefinieren. Wenn du einem Stream erlaubst, dass er sich um solche Formatierungen kümmert, musst du auch eine lösung für das Problem finden, dass eine Eingabe im einen Format ankommt und in einem anderen wieder ausgegeben werden soll.
also string1->zahl->string2(anderes zahlenformat). Das geht eigentlich nur, wenn jeder String sein eigenes locale mit sich rumschleppt, und dadurch wird er groß, kompliziert und träge.
In Java ist das nicht so extrem schlimm, weil man sich im Desktopbereich nicht soviel mit locales rumschlagen muss, die meisten Nutzer sind froh, wenn ein und ausgabe dasselbe Format haben. Da dies in C++ allerdings nicht vorausgesetzt werden kann, muss man solche Probleme lösen.
Ähnliches bei den Formatierungen in verschiedene Kodierungen. Das ist eigentlich nicht aufgabe eines streams. Da brauch man sich doch nur mal umschauen wo die Kodierung wichtig wird: bei der ein- und ausgabe. Bei der eingabe wird, soweit erforderlich der String in die programminterne Codierung umgewandelt, und bei der Ausgabe von der Internen Codierung in das Ausgabeformat. Es besteht also keine erforderlichkeit, diese Funktionalität aus den streams auszulagern.
Momentan haben wir in C++ eine schöne einteilung: Streambuffer,stream und String. jeder Teil hat eine eigene, von den anderen Teilen abgegrenzte Aufgabe. Und das ist technisch eine sehr schöne Sache.
-
otze schrieb:
In Java ist das nicht so extrem schlimm, weil man sich im Desktopbereich nicht soviel mit locales rumschlagen muss....
wieso desktop? Java ist im serverbereich auch sehr beliebt.
-
Cool, danke für die guten Erläuterungen!
-
otze schrieb:
Ähnliches bei den Formatierungen in verschiedene Kodierungen. Das ist eigentlich nicht aufgabe eines streams. Da brauch man sich doch nur mal umschauen wo die Kodierung wichtig wird: bei der ein- und ausgabe. Bei der eingabe wird, soweit erforderlich der String in die programminterne Codierung umgewandelt, und bei der Ausgabe von der Internen Codierung in das Ausgabeformat. Es besteht also keine erforderlichkeit, diese Funktionalität aus den streams auszulagern.
Halte ich so pauschal nicht für ganz richtig.
Man muss IMHO unterscheiden zwischen Textstreams und Bytestreams. Ich habe einen Haufen Strings, den stopfe ich in einen Textstream. Der Textstream wird von einem Encoder (z.B. UTF-8) gelesen, der einen Bytestream ausgibt, der dann schließlich in eine Datei geschrieben wird. So hat jede Komponente seine Aufgabe und die Komponenten lassen sich einzeln leicht austauschen.
Ich wüsste jetzt auch nicht, warum das, was du als "Stream" bezeichnest, nämlich der Bytestrom, der in die Datei schreibt, für evtl. Formatierungen von Zahlen zuständig sein sollte. Das klappt nur wenn byte == Zeichen, was nicht gerade eine zukunftssichere Annahme ist. Das bisherige Konzept in der C++ Standardbibliothek sieht nach meinem Verständnis keine Textstreams vor, oder eben nur unter der Annahme, dass byte == Zeichen. Das zeigen auch so Sachen wie eine Datei "als Text" öffnen. Sowas ist IMHO fix und fertig, eine Datei sollte immer als Bytestrom geöffnet werden und was dann reingeschrieben wird, hat so einen Stream nichts anzugehen.
-
c++ hat eben den ansatz dass ein stream formatierungen enthalten kann. wenn ich das nicht will, kann ich in jeden stream immer auch einfach bytefolgen reinwerfen.
die trennung ist bei java imho etwas sauberer gelöst, wenn auch sehr nervig - da ich dauernd adapter erstellen muss. c++ ist da eben pragmatischer was auf dem papier nicht ganz so sauber ist, aber in der verwendung eigentlich ganz praktisch ist.
-
Shade Of Mine schrieb:
c++ hat eben den ansatz dass ein stream formatierungen enthalten kann. wenn ich das nicht will, kann ich in jeden stream immer auch einfach bytefolgen reinwerfen.
die trennung ist bei java imho etwas sauberer gelöst, wenn auch sehr nervig - da ich dauernd adapter erstellen muss. c++ ist da eben pragmatischer was auf dem papier nicht ganz so sauber ist, aber in der verwendung eigentlich ganz praktisch ist.
Ich finde es nicht falsch, wenn ein Stream formattiert - aber das sollte nicht der selbe Stream sein, der eine Bytefolge in eine Datei schreibt. Es sollte ein Textstream sein. Diese Konzepte würde ich auf jeden Fall trennen. Ich denke auch, dass es damals einfach noch kein Thema war, dass byte != Zeichen. Von daher kein Vorwurf, ich würde nur das System heute so nicht als löblich hinstellen.
-
otze schrieb:
In Java ist das nicht so extrem schlimm, weil man sich im Desktopbereich nicht soviel mit locales rumschlagen muss, die meisten Nutzer sind froh, wenn ein und ausgabe dasselbe Format haben. Da dies in C++ allerdings nicht vorausgesetzt werden kann, muss man solche Probleme lösen.
C++ ist doch auf dem Desktopbereich viel mehr vertreten als Java.
Zeigt mal nen C++ Beispielcode mit locales, dass man in Java nicht so einfach hin bekommt.
-
Optimizer schrieb:
Shade Of Mine schrieb:
c++ hat eben den ansatz dass ein stream formatierungen enthalten kann. wenn ich das nicht will, kann ich in jeden stream immer auch einfach bytefolgen reinwerfen.
die trennung ist bei java imho etwas sauberer gelöst, wenn auch sehr nervig - da ich dauernd adapter erstellen muss. c++ ist da eben pragmatischer was auf dem papier nicht ganz so sauber ist, aber in der verwendung eigentlich ganz praktisch ist.
Ich finde es nicht falsch, wenn ein Stream formattiert - aber das sollte nicht der selbe Stream sein, der eine Bytefolge in eine Datei schreibt. Es sollte ein Textstream sein. Diese Konzepte würde ich auf jeden Fall trennen. Ich denke auch, dass es damals einfach noch kein Thema war, dass byte != Zeichen. Von daher kein Vorwurf, ich würde nur das System heute so nicht als löblich hinstellen.
Unicode geht auf 1987 zurueck. 1990 waren bereits Sun, Microsoft, und paar andere dabei, 1991 wurde das erste Buch des Unicode Standards veroeffentlicht, 1992 das zweite.
Im 1987 Original wurde schon an 16bit pro Zeichen gedacht. UTF wurde angefangen 1992 und damals war 32bit fuer ein Zeichen. Die vorletze Spezifikation von C++ war 1998, die letzte 2003. Da war wohl genuegent Zeit...
Ich persoehnlich finde die ganze Sprachunterstuetzung und Formate nur ein Haufen Chaos. Ist alles nur Halbherzig dahingemacht und voller Kompromisse. Das zieht sich durch von normalen Windows-Anwendungen ueber Emails und bis ins Internet.
-
wayne??? schrieb:
Zeigt mal nen C++ Beispielcode mit locales, dass man in Java nicht so einfach hin bekommt.
cin.imbue(locale1); int i; cin>>i; cout.imbue(locale2); cout<<i;
@optimizer
Ich finde es nicht falsch, wenn ein Stream formattiert - aber das sollte nicht der selbe Stream sein, der eine Bytefolge in eine Datei schreibt. Es sollte ein Textstream sein. Diese Konzepte würde ich auf jeden Fall trennen.
Vielleicht reden wir aneinander vorbei. aber das ist doch in C++ getrennt. Der stream formatiert, der buffer schreibt. Es ist also nicht dasselbe Objekt.