C++ Gurus
-
Jester schrieb:
Ich finde den Code jetzt auch nicht sonderlich kryptisch. Man muß sich in die Sache halt mal ne Zeit reinlesen.
Ich kenne eigentlich keine Sprache, die so viele Schüsselwörter und syntaktischen Overhead braucht, um so wenig Abstraktionsmechanismen bereitzustellen wie C++. Du?
-
besser schrieb:
template<typename ResultType, class ClassType>
Bei mir ist immer alles was einen Großbuchstaben am Anfang hat ein Typ. Aber ein ResultType würde natürlich kein bisschen schaden. Lieber mehr schreiben als zu wenig.
-
Shade Of Mine schrieb:
besser schrieb:
template<typename ResultType, class ClassType>
Bei mir ist immer alles was einen Großbuchstaben am Anfang hat ein Typ. Aber ein ResultType würde natürlich kein bisschen schaden. Lieber mehr schreiben als zu wenig.
Wie wär's mit ResultT & ClassT? Zu viel schreiben (-> Detailgrad vs Übersichtlichkeit) ist ähnlich grässlich wie zu wenig...
-
oder sollte Class besser ObjectType bzw. ObjectT heissen?
-
Shade Of Mine schrieb:
Aber ein ResultType würde natürlich kein bisschen schaden.
doch.
rutsch bitte nicht ins suboptimale ab.
-
volkard das ist reine geschmackssache.
-
Man kann natürlich auch ein
#define ganzzahltyp int #define fliesskomma float etc. for (ganzzahltyp laufvariable = 0; laufvariable < maximale_anzahl_schleifendurchgaenge; laufvariable = laufvariable + 1) { ... }
machen, aber in wiefern das dann lesbarer sein soll ...
Ich weiß nicht genau, aber ich glaube ich habe im Scott Meyers gelesen, dass man sich an folgendes halten sollte
So viel wie nötig, so wenig wie möglich.
Das Zitat bezog sich zwar auf Schnittstellen von Klassen, aber ich denke, das kann man auf den gesamten Stil anwenden und dann fährt man ganz gut damit, wobei das Nötige natürlich immer etwas subjektiv ist.
Beifor (int i = 0; i < max; ++i) { ... }
weiß auch jeder was gemeint ist, und das ist imo wesentlich übersichtlicher.
-
volkard schrieb:
Shade Of Mine schrieb:
Aber ein ResultType würde natürlich kein bisschen schaden.
doch.
rutsch bitte nicht ins suboptimale ab.Ich würde es nicht schreiben, weil es bei einem Stil redundant ist (das R sagt ja schon, dass es ein Typ ist) aber ein ResultType würde ich lieber lesen als ein R
mantiz schrieb:
Man kann natürlich auch ein
#define ganzzahltyp int
#define fliesskomma float
etc.Blödsinn. int ist ein synonym für ganzzahltyp, soetwas macht keinen Sinn.
Ich weiß nicht genau, aber ich glaube ich habe im Scott Meyers gelesen, dass man sich an folgendes halten sollte
So viel wie nötig, so wenig wie möglich.
Und? Inwiefern spricht das für ein
M<K, V<X> >?
Wenn man ein
Map<Key, Value<Whatever> >
haben kann?for (int i = 0; i < max; ++i) { ... }
weiß auch jeder was gemeint ist, und das ist imo wesentlich übersichtlicher.
Deshalb haben wir ja gesagt: bei i ist es OK, aber bei K X R T C etc. ist nix klar...
-
Deswegen hab' ich ja gesagt, dass es wohl immer ein wenig subjektiv ist. Wenn ich weiß, dass K für Key und V für Value steht, dann geht das auch nur mit Buchstaben. Ich persönlich würde in diesem Fall auch Key und Value bevorzugen, X würde ich aber beibehalten.
Das mit den defines war ja jetzt nur ein Beispiel, ich habe auch schon mit Leuten gesprochen, die die geschweiften Klammern als ein Beispiel für die Unlesbarkeit von z.B. C++ halten, wobei ich mich dann aber frage, wieso man ein BEGIN...END-Konstrukt für lesbarer hält. Alles andere ist und bleibt eine Stilfrage, die wohl immer subjektiv bleibt, aber nichts mit der Sprache zu tun hat.
Jeder schreibt seinen Code, glaube ich, erstmal so, dass man ihn selbst am Besten lesen kann, danach erst macht man sich Gedanken, ob dieser wohl auch für andere gut lesbar ist. Zumindest ist es bei mir so. Was habe ich von Code, den andere evtl. gut lesen können, ich mich beim lesen aber immer über unnötigerweise ausformulierte Bezeichnungen ärgern muss?
Wenn ich, wie in einem Beispiel weiter oben, weiß, dass pmf für Pointer (to) Member Function steht, dann geht es glaube ich nicht lesbarer.
-
mantiz schrieb:
Deswegen hab' ich ja gesagt, dass es wohl immer ein wenig subjektiv ist. Wenn ich weiß, dass K für Key und V für Value steht, dann geht das auch nur mit Buchstaben. Ich persönlich würde in diesem Fall auch Key und Value bevorzugen, X würde ich aber beibehalten.
Wofür steht X?
eXtendend? eXtension? eXtra? etwas anderes? Welche Rolle spielt es? Ist K nun wirklich Key oder doch eher ein Fachbegriff aus der Domain?Das mit den defines war ja jetzt nur ein Beispiel, ich habe auch schon mit Leuten gesprochen, die die geschweiften Klammern als ein Beispiel für die Unlesbarkeit von z.B. C++ halten, wobei ich mich dann aber frage, wieso man ein BEGIN...END-Konstrukt für lesbarer hält. Alles andere ist und bleibt eine Stilfrage, die wohl immer subjektiv bleibt, aber nichts mit der Sprache zu tun hat.
Gut, aber wir sind da wohl ein anderes Level...
Jeder schreibt seinen Code, glaube ich, erstmal so, dass man ihn selbst am Besten lesen kann,
Genau das ist aber falsch. Wenn wir jetzt mal von Teams ausgehen, denn wer schreibt schon Code nur für sich alleine (doch nur als Hobby und dann ist es ja wirklich egal, weil man jederzeit alles wegwerfen und nochmal beginnen kann).
Was habe ich von Code, den andere evtl. gut lesen können, ich mich beim lesen aber immer über unnötigerweise ausformulierte Bezeichnungen ärgern muss?
Schau dir meinen Code an. wenn wir von mem_fun_adapter absehen, was kannst du daran schwer lesen?
Wenn ich, wie in einem Beispiel weiter oben, weiß, dass pmf für Pointer (to) Member Function steht, dann geht es glaube ich nicht lesbarer.
pmf? Ja _wenn_. Bei "Method method" ist es sofort klar. Meinetwegen nenne es MethodPointer. Aber du erkennst es ohne acronym was es bedeutet. Bei "method" weisst du es auch ohne direkten Kontext worum es geht, bei pmf nicht unbedingt. Ich assoziiere zB pmf mit
p -> ungarisch für Zeiger
m -> ungarisch für Member
f -> name der VariablenNatürlich ist Stil subjektiv, aber ein
M<K, V<X> >
ist trotzdem eine Katastrophe...
Es gibt einfach keinen Grund einer Variable nur einen Buchstaben als Namen zu geben. i, j, k, l ausgenommen, denn diese sind wiederum standardisiert für Schleifen und dürfen nirgends anders verwendet werden.Ich verstehe diese einbuchstaben Typen nicht. Denn es ist wirklich nur ein Template Phänomen. Niemand würde
struct V { string name; int foo; };
schreiben. Aber ein
template<typename V> struct Value { V value; };
ist 'OK'.
Verstehe ich nicht, denn eine logische Argumentation dafür gibt es nicht.
-
Halt ich durchaus für verständlich und lesbar, da sich der einzige Bezug innerhalb von 5 Zeilen befindet.
Genausowenig habe ich etwas allgemeine Laufvariablen für Schleifen jeglicher Art
in der Art der Mathematiker als i,j,k... zu bezeichnen.Haben die Laufvariablen einen besonderen Sinn, so ziehe ich kurze sperechende Namen vor.
Genauso heißen temporäre Variablen für Zwischenergebnisse ohne weiteres temp, tmp,... oder Arbeitsstrings buffer. Sobald aber ein buffer "InputBuffer", der aus einem File gelesen wird, nach dem Entfernen von Beiwerks wie cr\lf, führenden und schließenden Whitespacees in z.B. Kommandos und Parameter zerlegt wird, so heißen
die entsprechenden Elemente dann auch command und param (respektive param[i])ganz nach dem hier schon benannten Motto
So viel wie nötig, so wenig wie möglich.
Zu lange Namen, die auch nur Redundanzen ausdrücken verwirren genauso, wie kryptischer AbKüFi mancher PseudoProfis. Was oftmals wichtiger ist, ist eine vernünftige Dokumentation und auch diese kurz prägnant und richtig, und am besten im Sourcecode.
-
hauptsache es
fktiniert
-
Shade Of Mine schrieb:
Ich verstehe diese einbuchstaben Typen nicht. Denn es ist wirklich nur ein Template Phänomen. Niemand würde
struct V { string name; int foo; };
schreiben. Aber ein
template<typename V> struct Value { V value; };
ist 'OK'.
Verstehe ich nicht, denn eine logische Argumentation dafür gibt es nicht.
Ich verstehe dein Problem hierbei nicht wirlich. Wenn du aus dem V ein T für Type oder gleich direkt Type machst ist doch offensichtlich was da steht!? Und so direkt vergleichbar ist es mit deinem struct V nicht, von daher ist mir etwas unklar auf welcher Basis du logische Argumente forderst.
-
finix schrieb:
Ich verstehe dein Problem hierbei nicht wirlich. Wenn du aus dem V ein T für Type oder gleich direkt Type machst ist doch offensichtlich was da steht!?
So kann man bei allem argumentieren.
Und so direkt vergleichbar ist es mit deinem struct V nicht
Wieso denn nicht?
-
Michael E. schrieb:
finix schrieb:
Ich verstehe dein Problem hierbei nicht wirlich. Wenn du aus dem V ein T für Type oder gleich direkt Type machst ist doch offensichtlich was da steht!?
So kann man bei allem argumentieren.
Wäre mir neu.
Michael E. schrieb:
Und so direkt vergleichbar ist es mit deinem struct V nicht
Wieso denn nicht?
Weil es eine völlig andere Situation ist?
-
Stimmt, irgendwie kommt dies häufig bei Templates vor, zumindest soweit ich das bis jetzt sagen kann, soweit reicht meine Erfahrung da noch nicht. Aber wenn ich eine kleine Funktion oder Klasse habe, dann ist da das "T" eigentlich genauso logisch, wie das "i" in einer Schleife. Wenn ich eine große Template-Klasse habe und/oder mit verschiedenen Templatetypen, dann ist es sicherlich übersichtlicher und auch sehr sinnvoll diese entsprechend zu benennen, aber wenn ich nur einen Typen in einem 3-Zeiler habe, dann erfüllt ein "T" denselben Effekt, wie ein "Type" oder was auch immer, jeder weiß, was gemeint ist, wenn ich ein Template mit einem Rückgabe-Typen und zwei Parametertypen beispielsweise habe, dann würde ich "TReturn", "TParam1", "TParam2" evtl. für sinnvoll halten. Bei einer gewissen Mächtigkeit, bei einem 3-Zeiler finde ich "R", "P1", "P2" oder ähnliches ähnlich verständlich und übersichtlich.
-
Wo ist denn das Problem dabei, auch template-Parametern einen guten Namen zu geben? Es hat sich doch schon allgemein die Erkenntnis durchgesetzt, dass sprechende Namen für Instanzen schön sind. Und das sprechende Namen für Typen schön sind. Wenn ich meine Klasse für eine Geldeinheit "Euro" nenne und nicht "E" ist das schöner. Kann man einsehen, oder?
Jetzt ist der Token "Euro", bzw. "E" doch wirklich nur ein Typname. Völlig egal, was es ist. Ungarische-Notations-Freaks können natürlich T_Euro oder C_Euro schreiben, das ist mir egal. Aber welchen logischen Grund gibt es jetzt, weniger gute Namen für typedefs und Template-Parameter zu nehmen, als für Klassen?Also, warum soll es jetzt böse sein, eine Map<KeyType, ValueType> zu haben? Wenn ich Map< schreibe, zeigt mir die IDE schön an, was reinkommt. Natürlich kann ich auch noch K und V interpretieren, ohne in die Hilfe sehen zu müssen. Spätestens beim dritten Parameter wird es aber eklig. Hier wird teilweise so getan, als wäre es ein Weltuntergang, einen vernünftigen Namen zu verwenden. *kopfschüttel*
Jetzt ist es ja noch nicht mal so, dass ich ständig KeyType und ValueType ausschreiben muss. Wenn ich die Map benutze, setze ich dafür einen konkreten Typ ein und schreibe höchstens diesen aus. Wenn ich die Map programmiere, benenn ich den Parameter halt nach der fertigstellung um, falls es mich wirklich stören sollte, ständig KeyType auszuschreiben. Das sind zwei Mausklicks in einer gescheiten IDE.
-
finix schrieb:
Michael E. schrieb:
finix schrieb:
Ich verstehe dein Problem hierbei nicht wirlich. Wenn du aus dem V ein T für Type oder gleich direkt Type machst ist doch offensichtlich was da steht!?
So kann man bei allem argumentieren.
Wäre mir neu.
Was verstehst du denn daran nicht / willst du nicht daran verstehen?
Michael E. schrieb:
Und so direkt vergleichbar ist es mit deinem struct V nicht
Wieso denn nicht?
Weil es eine völlig andere Situation ist?
Nö, es wird ein Typname gesucht.
-
Michael E. schrieb:
finix schrieb:
Michael E. schrieb:
finix schrieb:
Ich verstehe dein Problem hierbei nicht wirlich. Wenn du aus dem V ein T für Type oder gleich direkt Type machst ist doch offensichtlich was da steht!?
So kann man bei allem argumentieren.
Wäre mir neu.
Was verstehst du denn daran nicht / willst du nicht daran verstehen?
Ok, die Langversion, extra für dich: Es wäre mir neu dass man diese Argumentation, in sinnvoller Weise, bei "allem" anwenden könnte.
Was meinst du, nebenbei, mit "allem"?
Oder monierst du lediglich dass ich das Problem am konkreten Beispiel nicht entdecken kann?Michael E. schrieb:
Und so direkt vergleichbar ist es mit deinem struct V nicht
Wieso denn nicht?
Weil es eine völlig andere Situation ist?
Nö, es wird ein Typname gesucht.[/quote]
Es lebe die kontextfreie Simplifikation!! Hurra!// Anwendungscode: void bar() { Value<int> v1; v1.value = 42; V v2; v2.name = "whatever"; v2.foo = v1.value; }
Siehst du den Unterschied?
-
Ok, die Langversion, extra für dich: Es wäre mir neu dass man diese Argumentation, in sinnvoller Weise, bei "allem" anwenden könnte.
Was meinst du, nebenbei, mit "allem"?"Alles" im Sinne von "jeder Name". Guck dir zum Beispiel dieses Beispiel an:
template<typename EPdTunewlN, typename ZPdTunewlN> EPdTunewwlN EszVdFmewlN(EPdTunewlN EPdFmeaNadTP, ZPdTunewlN ZPdFmeaNadTP) { return static_cast<EPdTunewwlN>(EPdFmeaNadTP.ExbMffdmkNme(ZPdFmeaNadTP.EaaybMffdmkNme())); }
Legende:
Erster Parameter des Templates und ein wunderschöner langer Name
Zweiter Parameter des Templates und ein wunderschöner langer Name
Eine sinnfreie, zur Veranschaulichung dienende Funktion mit einem wunderschönen langen Namen
Erster Parameter der Funktion mit einem anderen Namen als die Template-Parameter
Zweiter Parameter der Funktion mit einem anderen Namen als die Template-Parameter
Eine x-beliebige Member-Funktion, für die mir kein Name mehr einfällt
Eine andere, also y-beliebige Member-Funktion, für die mir kein Name mehr einfälltJetzt kann ich auch argumentieren, wenn, ja wenn ich jetzt statt den Abkürzungen sinnvolle Namen benutze, "ist doch offensichtlich was da steht!?" (Zitat von dir).
Es lebe die kontextfreie Simplifikation!! Hurra!
Du führst die Simplifikation ein, indem du nur auf den Anwendungscode schaust.