C++ Gurus



  • Wie schon gesagt:
    Es geht nicht um falsch.

    Außer bei z.B. for (int i = 0 habe ich noch nie Variablennamen,etc. genommen wie Z,X, oder was auch immer. Mir ging es um die Namen. Warum muss man hier einzelne Buchstaben verwenden.
    Da könnte ich ja auch gleich jede Methode von A - Z benennen.
    Dadurch ist es auf den ersten Blick sehr kryptisch und ein einziger Buchstabensalat.



  • Dann mußte aber auch konsequent weiter schauen und sehen, daß es vielleicht ne Konvention ist. Und gerade bei ner STL-Implementierung scheint das so auch recht sinnvoll zu sein.

    Also ist es ein Beispiel wie man es richtig macht und nicht das Gegenteil wie Du behauptet hattest, oder?



  • Jester schrieb:

    Dann mußte aber auch konsequent weiter schauen und sehen, daß es vielleicht ne Konvention ist. Und gerade bei ner STL-Implementierung scheint das so auch recht sinnvoll zu sein.

    Begründung?

    T für Type ist das höchste aller Gefühle, ein Type tut da aber auch nicht weh.

    Bei einem
    K<V, T<X> >
    wird es dann aber wirklich doof...

    Den Code mit dem op+ habe ich jetzt nicht gefunden, aber ein andere Code hier im Thread:

    template< class R, class T >
    class mem_fun_t : public unary_function<T*, R>{    
    R( T::*pmf)();  
    public:    explicit mem_fun_t( R( T::*f )() ) : pmf(f) {}    
    R operator()( T* t ){ return t->*pmf(); }}
    
    template< class R, class T >mem_fun_t< R, T > mem_fun( R( T::*pmf )() ){    return mem_fun_t< R, T >( pmf );}
    

    autsch. Sieht aus wie aus einer STL Implementierung geklaut. Und die sind idR einfach nur mist.

    Meine Idee:

    template<typename Result, class Class>
    class mem_fun_adapter : public unary_function<Class*, Result>
    {
    public:
      typedef Result (Class::*Method)();
    
    private:
      Method method;
    
    public:
      explicit mem_fun_adapter(Method method)
      : method(method)
      {}    
    
      Result operator()(Class* object)
      {
        return object->*method();
      }
    }
    
    template<typename Result, class Class>
    mem_fun_adapter<Result, Class> mem_fun(Result (Class::*method)())
    {
      return mem_fun_adapter<Result, Class>(method);
    }
    

    Jetzt haben wir 2 häßliche stellen:
    object->*method()
    und
    Result (Class::*method)()
    aber da ist die Syntax einfach so, das geht kaum schöner.



  • template<typename ResultType, class ClassType>



  • 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.
    Bei

    for (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 Variablen

    Natü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.


Anmelden zum Antworten