Welche C++11 Features verwendet ihr häufig?


  • Mod

    Singender Holzkübel schrieb:

    Und std::initializer_list (sehr praktisch)

    Wofür denn das?



  • Arcoth schrieb:

    Singender Holzkübel schrieb:

    Und std::initializer_list (sehr praktisch)

    Wofür denn das?

    ich vermute, damit er seine eigenen klassen wie aggregate initialisieren kann.



  • Arcoth schrieb:

    Singender Holzkübel schrieb:

    Und std::initializer_list (sehr praktisch)

    Wofür denn das?

    Diverse Initialisierungen.

    Arcoth schrieb:

    Und was benutzt ihr aus C++1y?

    constexpr 😉



  • Arcoth schrieb:

    Und was benutzt ihr aus C++1y?

    Nichts.

    Aber ich freue mich schon ein bisschen auf polymorphe Lambdas und Return-Type Deduction für "normale" Funktionen. Letzteres ist ja besonders für Template-lastigen Code interessant. Damit könnte ich mir hier z.B. die nervigen "->decltype(...)" sparen.



  • Singender Holzkübel schrieb:

    Arcoth schrieb:

    Und was benutzt ihr aus C++1y?

    constexpr 😉

    das gibt es schon in c++11.



  • Gibts da eigentlich irgendwo eine nette Übersicht für C++1Y Features?



  • asfdlol schrieb:

    Singender Holzkübel schrieb:

    Arcoth schrieb:

    Und was benutzt ihr aus C++1y?

    constexpr 😉

    das gibt es schon in c++11.

    Ja, aber nicht so!



  • Ich liste hier nur die am häufigsten benutzten C++11-Features auf.

    Sprache: Lambda-Ausdrücke, auto , Range-Based For, Move-Semantik, nullptr

    Bibliothek: function , unique_ptr



  • Lambda, move, forward, auto, range based for, sämtliche neuen Methoden von Containern sowie neue Algorithmen, unique_ptr, shared_ptr (eigentlich nur bei dem einen Projekt), nullptr.



  • nullptr ist einfach toll, lambdas und diverse neue Container-Funktionen. Der Rest taucht mal so hin und wieder auf, wenn ich merke dass man manche Dinge mit C++11 Features übersichtlicher/schneller/schöner/besser lösen kann.^^



  • Sprache: Move-Semantic, auto, variadic templates
    Library: unique_ptr, hashmaps

    Was ich nicht oder äusserst selten verwende:
    initializer_list, shared_ptr, foreach (wozu?), Encoding-Facetten.

    Was ich aus C++14 vermisse:
    Return-Type-Deduction, polymorphe Lambdas und Concepts.



  • fgbjaeh schrieb:

    Was ich nicht oder äusserst selten verwende:
    ... foreach (wozu?)

    Gibt's in C++ ja auch nicht



  • fgbjaeh schrieb:

    Concepts

    Achja. Das gibt's ja auch noch (irgendwann vielleicht mal).

    /me ist froh, dass "concepts" aus dem C++0x draft rausgeflogen ist und freut sich auf ein entschlacktes "concepts lite".



  • Ich nutze

    `auto

    nullptr,

    std::function

    std::unique_ptr

    std::shared_ptr

    `

    ich habe eine Frage bezüglich std::enable_if<Bool,T>

    Also wenn der Bool wahr ist, dann hat die Funktion ein Rückgabewert?

    also als beispiel:

    #ifndef _BEISPIEL_HPP
    #define _BEISPIEL_HPP
    
    #ifdef _NO_EXCEPTIONS
    #define _EXAMPLE_ true
    #else
    #define _EXAMPLE_ false
    #endif
    
    ...
    std::enable_if<_EXAMPLE_,DWORD>::type foo(parameters x)
    {
       //DO something
      if(/*ERROR*/)
          #ifdef _NO_EXCEPTIONS_
              return 3;
          #else
             throw "You made an ERROR";
          #endif
    
    return 0; // wird Ende der Funktion trotzdem ein return gemacht?
    }
    ...
    
    #endif
    

  • Mod

    Aber ich freue mich schon ein bisschen auf polymorphe Lambdas und Return-Type Deduction für "normale" Funktionen. Letzteres ist ja besonders für Template-lastigen Code interessant.

    Benutze ich beides laengst, den ich habe den neusten GCC- und Clang-Snapshot. Ich habe schon die Angewohnheit, gar keine Rueckgabetypen mehr hinzuschreiben, ausser, ich moechte noch implizit konvertieren. Ist ausserst angenehm, weil so die Redundanz aus dem Typsystem entfernt wird.

    Also wenn der Bool wahr ist, dann hat die Funktion ein Rückgabewert?

    Nein. Falls, und nur falls der bool den Wert true hat, dann hat die Spezialisierung einen Member mit Namen type - das ist ein Typedef auf das zweite Template-Argument. enable_if nutzt man fuer SFINAE, u.a. auch um Funktionen unter bestimten Bedingungen aus dem Overload-Set zu schmeissen. Wenn der bool den Wert false hat, dann ist der Ausdruck std::enable_if<....>::type fehlerhaft. Das ist der Trick. Seit C++11 kann man so etwas fuer Ausdruecke teilweise auch ohne enable_if , mit trailing-return-types und decltype .

    Kurz: Macht nur mit Templates Sinn.

    Falls du nur einen Compile-time Pruefung auf etwas machen willst, nimm

    static_assert( /*eine Bedingung */ false, "Fehlermeldung" );
    


  • Arcoth schrieb:

    Ich habe schon die Angewohnheit, gar keine Rueckgabetypen mehr hinzuschreiben, ausser, ich moechte noch implizit konvertieren. Ist ausserst angenehm, weil so die Redundanz aus dem Typsystem entfernt wird.

    Hier sehe ich aber ein ähnliches Problem wie bei auto , wenn mit Typinferenz übertrieben wird: Code wird schlechter lesbar. Bei sehr generischem oder templatelastigem Code und in lokal begrenztem Kontext sind solche Features äusserst nützlich, aber für normale Anwendung nicht unbedingt.

    Gerade bei Funktionen ist ja die Signatur das API; wenn ich nun die Implementierung anschauen muss, um den Rückgabetyp zu kennen, läuft etwas falsch...



  • Nexus schrieb:

    Arcoth schrieb:

    Ich habe schon die Angewohnheit, gar keine Rueckgabetypen mehr hinzuschreiben, ausser, ich moechte noch implizit konvertieren. Ist ausserst angenehm, weil so die Redundanz aus dem Typsystem entfernt wird.

    Hier sehe ich aber ein ähnliches Problem wie bei auto , wenn mit Typinferenz übertrieben wird: Code wird schlechter lesbar. Bei sehr generischem oder templatelastigem Code und in lokal begrenztem Kontext sind solche Features äusserst nützlich, aber für normale Anwendung nicht unbedingt.

    Vorallem explodieren dann die Compiler-Fehlermeldungen, wenn was nicht stimmt.



  • apropos zu viel type deduction ... im Rahmen von concepts lite tauchen ja concepts dort auf, wo sonst eigentlich typen stehen, was dann ein "implizites template" in Fall von Funktionen wäre:

    void show(Sequence const& x)
    {
      for (auto& e : x) {
        cout << e << endl;
      }
    }
    

    Könnte mir auch vorstellen, zwecks Konsistenz, dass man dann vielleicht auch das hier schreiben könnte:

    Iterator b = myvector.begin();
    

    statt

    auto b = myvector.begin();
    

    Gut, man kann auch diese Information, dass es sich um einen Iterator handelt, in den Namen des Objekts packen, aber das würde ggf zu lästig mit dem Tippen, wenn man sich mehr als einmal drauf beziehen will.


  • Mod

    Vorallem explodieren dann die Compiler-Fehlermeldungen, wenn was nicht stimmt.

    Bitte ein Beispiel. Wieso sind die Fehlermeldungen mit Deduzierung größer als ohne?

    Gerade bei Funktionen ist ja die Signatur das API; wenn ich nun die Implementierung anschauen muss, um den Rückgabetyp zu kennen, läuft etwas falsch...

    Das meinte ich definitiv nicht für APIs! Ich habe das nicht einmal in einem richtigen Projekt genutzt, nur für kleine Sachen oder ein paar hundert Code-Zeilen. Da ist es in der Tat angenehm. Bei größeren Projekten ist das nicht mehr ganz so toll, weil dann tatsächlich der Rückgabetyp von der IDE nicht deduziert wird (kommt noch :p), und man da den Überblick verliert.

    @kkaw:
    Man sieht direkt am Code, dass es ein Iterator ist, dafür braucht man weder den Typen noch den Namen. Ich meine, schließlich sind deine Funktionen nur etwa höchstens fünfzehn Zeilen lang, oder?



  • Ich kann nicht mehr warten auf:

    "abc"s // user defined literal: const char* -> string
    

Anmelden zum Antworten