Sprachmittel, die ihr nie benutzt



  • Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?

    Also dass pointer[index] einfach zu *(pointer+index) wird, und man es daher auch als index[pointer] schreiben kann?

    Das ist nämlich auch was was ich nie verwende.



  • Interessanter wird es doch bei der Frage: Auf was könntet ihr verzichten? Also bei mir wären da nur Trigraphen, register, auto. Wobei auto von C++11 wohl eh eine neue Bedeutung bekommt.



  • hustbaer schrieb:

    Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?

    Es ist eher die Symmetrie des eingebauten Plus-Operators.



  • Sprachmittel, die ich nie einsetze:

    • Exception-Spezifikationen
    • variable Argumentlisten
    • Speicherklassen-Schlüsselwörter register und auto
    • protected -Vererbung
    • Pointer-to-Member (nicht Memberfunktionszeiger)
    • Bitfelder
    • Digraphen, Trigraphen, alternative Schlüsselwörter ( and etc.)
    • export
    • eigene new - und delete -Operatoren
    • union
    • goto
    • volatile
    • Arrays
    • C-String

    Sprachmittel, die ich selten einsetze:

    • Globale Variablen (und wenn auch nur für Objekt-Registrierung an anderen Klassen, oder Konstanten).
    • #define (Nur für Headerguards und bedingte Compilierung, niemals für Konstanten und Funktionsersatz)
    • delete (In der Regel ziehe ich Smartpointer wie scoped_ptr/unique_ptr & Co vor).


  • volkard schrieb:

    hustbaer schrieb:

    Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?

    Es ist eher die Symmetrie des eingebauten Plus-Operators.

    Hihi, OK.
    Dann eben dass der Indexing-Operator auf *(a+b) abgebildet wird.
    Und Symmetrie ist sicher auch der falsche Ausdruck, aber ich glaube ihr versteht was ich meine.



  • hustbaer schrieb:

    volkard schrieb:

    hustbaer schrieb:

    Wurde die Symmetrie des eingebauten Indexing Operators schon genannt?

    Es ist eher die Symmetrie des eingebauten Plus-Operators.

    Hihi, OK.
    Dann eben dass der Indexing-Operator auf *(a+b) abgebildet wird.

    Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.



  • Bashar schrieb:

    Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.

    Wo sonst? Und findest du die Nicht-Kommutativität bei std::string sinnvoll?



  • Nexus schrieb:

    Bashar schrieb:

    Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.

    Wo sonst? Und findest du die Nicht-Kommutativität bei std::string sinnvoll?

    Da war die Wahl de Zeichens '+' eine unglückliche Wahl.



  • Nexus schrieb:

    Bashar schrieb:

    Das ist soweit eigentlich OK, es ist wirklich die Kommutativität von +, die nicht immer sinnvoll ist.

    Wo sonst? Und findest du die Nicht-Kommutativität bei std::string sinnvoll?

    Ja klar, warum nicht?



  • volkard schrieb:

    Nexus schrieb:

    Wo sonst? Und findest du die Nicht-Kommutativität bei std::string sinnvoll?

    Da war die Wahl de Zeichens '+' eine unglückliche Wahl.

    Das ist Geschmackssache, ich finde es jedenfalls durchaus intuitiv bei der Anwendung.



  • asc schrieb:

    Das ist Geschmackssache, ich finde es jedenfalls durchaus intuitiv bei der Anwendung.

    Ich finde . und & auch nicht schlecht, in Basic-Dialekten, wo + und & gehen, bevorzuge ich &.


  • Mod

    Hier auch mal mein Senf, falls es jemandem interessiert:
    Sprachmittel, die ich nie einsetze:

    • Exception-Spezifikationen
    • variable Argumentlisten
    • Speicherklassen-Schlüsselwörter register und auto (in seiner alten Bedeutung)
    • Pointer-to-Member (nicht Memberfunktionszeiger) (nur mal versehentlich, als ich einem Compilerfehler begegnet bin)
    • Function-Style- und C-Casts
    • Bitfelder
    • Digraphen, Trigraphen (man beachte, dass ich die alternativen Schlüsselwörter ausdrücklich benutze!)
    • export
    • eigene new - und delete -Operatoren
    • dynamic_cast
    • union
    • goto , Labels
    • volatile
    • Inline-Assembler
    • wchar_t , wide Strings & Co.
    • Lokale Klassen (d.h. Klassen in Funktionen, nicht Klassen in Klassen)
    • operator->* , operator~
    • Überladung von: operator->* , operator& , operator~ , operator+ (unär), logische Verknüpfungsoperatoren.
    • Präprozessordirektiven: #line, #error, Nulldirektive 😃 , im Standard vordefinierte Makros (die sind total nutzlos!)

    Sehr selten:

    • virtuelle Vererbung
    • Funktionstemplate-Spezialisierung
    • const_cast
    • Arrays
    • switch Ja, kaum zu glauben, aber es kommt einfach nie vor, außer bei Hausaufgaben im Forum.
    • mutable
    • explicit Auch kaum zu glauben. Aber meine Konstruktoren haben irgendwie immer entweder 2+-Argumente oder sollen tatsächlich implizit sein.
    • float, short, signed char, long double
    • continue
    • Überladung von: operator, , operator- (unär)

    Das ist meine Liste nach Durchgehen der Beiträge hier im Thread und Lesen der Überschriften im Standard bis Kapitel 17 (wo die Sprachbibliothek losgeht).



  • Ich kann im Wesentlichen Nexus zustimmen. Kleine Unterschiede/Ergänzungen:

    - Pointer-to-Member: Kommen hin- und wieder mal vor in Verbindung mit bind.
    - Spezialisierung von Funktions-Templates: Nie.
    - volatile: Nie.
    - Polymorphe Basisklassen sind immer abstrakt bei mir.



  • SeppJ, du hast noch einiges aufgezählt, das ich auch nie verwende. Z.B. Inline-Assembler, funktionslokale Klassen (deren Schicksal ist mit Lambdas eh besiegelt) und #line . Operatoren und Typen verwende ich auch nicht alle. Und die Nulldirektive kannte ich gar nicht, muss ich von nun an öfter einsetzen 🤡

    Aber wenn ich den C++-Standard kürzen müsste, würde ich wahrscheinlich mit all den alternativen Schreibweisen anfangen (besonders Di/Trigraphen benutzt eh niemand, und für die Schlüsselwörter reichen auch Makros :p). Exception-Spezifikationen sind wenigstens bald deprecated, export wird ganz entfernt. Bei VarArgs oder register wirds wohl wegen C-Kompatibilität noch ewig dauern, falls die überhaupt jemals rausfliegen. Der Rest sollte okay sein, auch wenn ich persönlich nicht Gebrauch davon mache.


  • Mod

    Nexus schrieb:

    Und die Nulldirektive kannte ich gar nicht, muss ich von nun an öfter einsetzen 🤡

    Ja, die war mir auch neu, ich bin nur im Standard drüber gestolpert und musst erst einmal lesen, was das überhaupt ist.



  • Nexus schrieb:

    Exception-Spezifikationen sind wenigstens bald deprecated, export wird ganz entfernt.

    Good point. Aber wieso ist im neuen Standard noexcept drin? Tut es nicht genau das selbe?



  • exceptthis schrieb:

    Good point. Aber wieso ist im neuen Standard noexcept drin? Tut es nicht genau das selbe?

    Nein, noexcept ist schon sinnvoll, um Funktionen mit Nothrow-Garantie kennzuzeichnen.

    Es gab hier schon ein paar Threads dazu, da könntest du Genaueres darüber finden. Z.B. ab hier (ist etwas viel Noise, beachte vor allem die Beiträge von krümelkacker und Shade Of Mine).



  • Nexus schrieb:

    SeppJ, du hast noch einiges aufgezählt, das ich auch nie verwende. Z.B. Inline-Assembler, funktionslokale Klassen (deren Schicksal ist mit Lambdas eh besiegelt)

    Sie sind erst mit dem C++0x Standard wirklich einsetzbar. Vorher konnten sie ja keine Templateargumente sein. Und für alles, was nur ein klein wenig komplizierter ist, sind lambdas eh unübersichtlich und funktionslokale Klassen auf einmal weit vorne.

    Ansonstne kann ich mich SeppJs Liste ganz gut anschließen. Mutable kommt bei mir momentan leider ein wenig zu häufig vor und dynamic_cast brauche ich leider auch ab und zu, da ich templates und abstrakte Interfaces unter einen Hut kriegen muss.

    und natürlich für sowas:

    Base* obj=...;
    OptimizedDerived* objOpt = dynamic_cast<OptimizedDerived*>(obj);
    if(objOpt){
        kernel=createOptimizedKernel(objOpt);
    }
    else
    {
        kernel=createStandardKernel(obj);
    }
    

    wenn mir jemand sagen kann, wie ich sowas ohne dynamic_cast lösen könnte, wäre ich dankbar. Ohne Abstrakte Basisklassen ist das ja trivial.



  • otze schrieb:

    Sie sind erst mit dem C++0x Standard wirklich einsetzbar. Vorher konnten sie ja keine Templateargumente sein. Und für alles, was nur ein klein wenig komplizierter ist, sind lambdas eh unübersichtlich und funktionslokale Klassen auf einmal weit vorne.

    Wirklich? Ich kann mir nicht vorstellen, die jemals gross einzusetzen. Sobald etwas ein wenig komplizierter wird, kommt es bei mir eh aus der Funktion raus in einen detail -Namensraum. Lambdas hingegen kann man schön für triviale Funktoren benutzen.

    otze schrieb:

    wenn mir jemand sagen kann, wie ich sowas ohne dynamic_cast lösen könnte, wäre ich dankbar. Ohne Abstrakte Basisklassen ist das ja trivial.

    Eine virtuelle Funktion in Base und OptimizedDerived geht nicht (z.B. wegen festgelegter Klassen)?

    Base* obj = ...;
    kernel = obj->createKernel();
    

  • Mod

    otze schrieb:

    und natürlich für sowas:

    Base* obj=...;
    OptimizedDerived* objOpt = dynamic_cast<OptimizedDerived*>(obj);
    if(objOpt){
        kernel=createOptimizedKernel(objOpt);
    }
    else
    {
        kernel=createStandardKernel(obj);
    }
    

    wenn mir jemand sagen kann, wie ich sowas ohne dynamic_cast lösen könnte, wäre ich dankbar. Ohne Abstrakte Basisklassen ist das ja trivial.

    Wäre das nicht einfach durch eine entsprechende virtuelle Funktion zu lösen?


Anmelden zum Antworten