C++ Standardisierung: Ein erster Blick auf die Papers & C++14



  • Kellerautomat schrieb:

    Swap Operator: Loest das ADL Problem, sehe aber nicht, warum man dafuer einen extra Operator einfuehren muss.

    Das ADL-Problem ist doch schon gelöst?

    std::iter_swap(&a, &b);
    

    quoted Strings: Endlich mal ein nuetzlicher Manipulator

    Macht die IOstreams immer noch nicht benutzbar. Ein getline-Manipulator wäre praktischer.

    Polymorphic Lambdas: Einfach nur haesslich. Meine Lambda-Lib (angelehnt an Boost.Lambda) ist immer noch schoener.

    Ich find das super. Damit sind Lambdas endlich einigermassen angenehm. Jetzt stört eigentlich nur noch das "return". Zeig mal deine Lambda-Lib.

    Unicode: Wurde langsam mal Zeit.

    Ja, das ist mal ein Anfang.



  • adli schrieb:

    Polymorphic Lambdas: Einfach nur haesslich. Meine Lambda-Lib (angelehnt an Boost.Lambda) ist immer noch schoener.

    Ich find das super. Damit sind Lambdas endlich einigermassen angenehm. Jetzt stört eigentlich nur noch das "return". Zeig mal deine Lambda-Lib.

    Die haetten einfach das 'auto' Keyword entfernen sollen. Boost.Lambda kannst du in der Doku nachsehen, ich hab da nur nen Rewrite mit ein paar C++11 Anpassungen gemacht.



  • otze schrieb:

    Gut, dann versuchen wir mal zu abstrahieren: welche bedeutenden Sonderfälle kennst du noch? ich sah und sehe das Problem bislang nur für Container in relevantem Ausmaß.

    Fällt mir gerade nicht viel ein, aber ohne dich wäre ich auch nicht auf die Container-Problematik aufmerksam geworden. Grundsätzlich klänge aber Decimads Vorschlag schon mal nach einer sehr guten Idee -- ob wir das in C++ brauchen, ist die andere Frage...

    otze schrieb:

    Es [Range zurückgeben] hilft zudem nicht bei Funktionsparametern, da muss der User den Wrapper bereit stellen, aber in der Signatur kann es Probleme geben(template deduktion).

    Hm, hier bin ich mir nicht sicher, wie du das meinst. Wie stellst du dir Range-Parameter vor? Es gibt ja mehrere Möglichkeiten, so eine Übergabe zu realisieren:

    // 1. Reiner Template-Parameter
    template <typename Range>
    void fn(Range r);
    
    // 2. Concepts (weiss nicht, wie die aktuellste Version aussieht)
    template <RandomAccessRange Range>
    void fn(Range r);
    
    // 3. Templatisierte Typen
    template <typename Itr>
    void fn(iterator_range<Itr> r);
    
    // 4. Type Erasure - kein Template
    void fn(type_erased_range<int> r);
    

    Kellerautomat schrieb:

    Die haetten einfach das 'auto' Keyword entfernen sollen.

    Edit: Stimmt, das haben sie im neuen Paper wieder revidiert. Und ich hab mich beim Lesen des Portland-Papers schon gefreut 😞

    Kellerautomat schrieb:

    Boost.Lambda kannst du in der Doku nachsehen, ich hab da nur nen Rewrite mit ein paar C++11 Anpassungen gemacht.

    Bei Boost.Lambda ist halt recht viel schwarze Magie dahinter. Du kannst zwar nett Ausdrücke basteln, aber nicht ganze Funktionen. Hast du mit deiner Bibliothek nicht sofort extrem verschachtelte Typen und lange Kompilierzeiten?



  • Nexus schrieb:

    Kellerautomat schrieb:

    Die haetten einfach das 'auto' Keyword entfernen sollen.

    Haben sie ja.

    Waere mir neu. Mein aktueller Stand ist:

    [] (auto x) {}
    

    ... was ja mal dermassen haesslich ist.

    Nexus schrieb:

    Kellerautomat schrieb:

    Boost.Lambda kannst du in der Doku nachsehen, ich hab da nur nen Rewrite mit ein paar C++11 Anpassungen gemacht.

    Bei Boost.Lambda ist halt recht viel schwarze Magie dahinter. Du kannst zwar nett Ausdrücke basteln, aber nicht ganze Funktionen. Hast du mit deiner Bibliothek nicht sofort extrem verschachtelte Typen und lange Kompilierzeiten?

    Doch, ich kann damit Funktionen bauen. if/else, try/catch, while/for, new/delete, alles dabei. Das mit den verschachtelten Typen ist zwar richtig, aber ich sehe nicht, warum das ein Problem sein sollte. Man nimmt ja eh auto dafuer, oder uebergibt es einem Funktionstemplate, z.B. einen std Algo. Ueber Kompilierzeiten kann ich nicht klagen.



  • So, nun ist auch Part 3 fertig.

    Diesmal mit concepts lite und transactional memory. Letztere ist wohl noch ziemlich unausgegoren.
    Weitere Highlights finde ich die letzten 3 Papers. N3595 und N3596 sind von Peter Gottschling.



  • "Wording for accessing Tuplefields by type", "Delimited Iterators" - Wer kommt auf solche unnötigen Vorschläge?

    Neue Allokatoren, Concepts Lite, make_unique, Relaxing constraints on constexpr functions : 👍



  • Eines meiner wtf-Hightlights aus den Papers ist:

    The primary implementation hurdle will be the implementation of an allocator that can provide executable memory, whereas traditional allocators do not provide such.

    N3574



  • Inwiefern WTF?


  • Mod

    Auf die if-Schleife habe ich gewartet...



  • Ethon schrieb:

    Inwiefern WTF?

    Naja, das eine Klasse ausführbaren speicher erzeugen kann.
    Nichts anderes ist ja ein allocator letzt endlich.



  • ausführbahren speicher

    Ausführbar?



  • camper schrieb:

    Auf die if-Schleife habe ich gewartet...

    Ja, und dann wird es auch noch in den Standard mit aufgenommen ...



  • Dann muss if-schleife.de wohl die Seite überarbeiten von

    Es gibt keine if-Schleifen.

    zu:

    Es gibt eine if-Schleife, aber wenn dieser Link gepostet wurde, verwechselst du das wahrscheinlich. Also eine if-Schleife sieht so aus... eine if-Abfrage dagegen...

    Warum klingt das so sehr nach C++? 😃


  • Mod

    cooky451 schrieb:

    Dann muss if-schleife.de wohl die Seite überarbeiten von

    Es gibt keine if-Schleifen.

    zu:

    Es gibt eine if-Schleife, aber wenn dieser Link gepostet wurde, verwechselst du das wahrscheinlich. Also eine if-Schleife sieht so aus... eine if-Abfrage dagegen...

    Warum klingt das so sehr nach C++? 😃

    Oder man kann den bequemen Weg gehen und einfach ein kleines "noch" einfügen.



  • Ich hätte da auch noch so eine Kleinigkeit bezüglich Schleifen.
    Ich brauche immer wieder Zähler.

    Wie wäre es, wenn man die Syntax eines for-init-statements entsprechend umändern würde zu

    for(forinitstatement  conditionopt;  expressionopt)    loopcountexpansionoptfor ( for-init-statement ~~ condition_{opt} ;~~ expression_{opt}) ~~~~ loop-count-expansion_{opt}

    loop-count-expansion:
         count(typeid   identifier;  integerliteralopt;  integerliteralopt)~~~~~ count ( type-id ~~~ identifier ;~~ integer-literal_{opt} ;~~ integer-literal_{opt} )

    Achtung: Wenn die loop-count-expansion genutzt wird, kann der in Klammern eingeschlossene Teil des for-Statements ( das (;;) ) weggelassen werden! Siehe unten für Beispiel.

    Die Deklaration des Namens identifier wäre auch im enclosing scope gültig, also auch nach dem for-statement, wo man dessen Wert prüfen könnte.

    Das erste Ganzzahlliteral sei X, das zweite Y.

    Weder X noch Y muss angegeben werden. Allerdings darf nie nur Y, aber nicht X angegeben werden.
    Wenn Y nicht angegeben wird, wird einfach weiter inkrementiert; wenn dann ein Überlauf stattfinden würde, wird ein range_error geworfen.
    Wenn Weder X noch Y angegeben werden, wird so getan als sei X als 0 angegeben.

    • Wenn die Kondition der eigentlichen Schleife nicht mehr gültig ist, bevor oder genau wenn der counter den End-Wert erreicht, wird nichts verändert, d. h. der Zähler hat den Wert den er zum Abbruchs-Zeitpunkt eben hatte.
    • Sollte allerdings der Wert darüber hinaus gehen, raised das Programm entweder einen SIGILL oder wirft eine std::range_error.
      Das wäre eine Frage an euch, was würde mehr Sinn machen.
      Y sollte man nur angeben, wenn man sicher ist, dass keiner der beiden auftreten soll, oder wenn man damit rechnet o. ä.

    Ich weiß, es ist Syntaxzucker. Wer nämlich jetzt noch nicht genau sieht, worauf ich hinaus will, der sieht es gleich:

    Einsatz:
    Statt

    int ct = 0;
    for( auto iter = ... ; ... ; ... )
    {
       // irgendein statement das einen Zähler wie ct braucht
       ++ct;
    }
    

    ==>

    for( auto iter = ... ; ... ; ...) count( int ct; )
       // irgendein statement das einen Zähler wie ct braucht
    

    Oder

    for count( int ct; 0 ; 10 ) // Bemerkung von oben.
        std::cout << ct << " bottles of beer ... ";
    

    (Sorry für das eklige Latex 😃 )

    Edit: Wenn die Idee nicht totaler Blödsinn ist, dann, so fällt mir gerade auf, sollte das ein Mod vielleicht splitten. 💡 (oder?)


  • Mod

    Das vermisse ich auch, Sone. Wobei mir deine Syntax nicht gefällt (ich aber auch nicht lange genug nachgedacht habe, um etwas besseres vorschlagen zu können).



  • Sone schrieb:

    Einsatz:
    Statt

    int ct = 0;
    for( auto iter = ... ; ... ; ... )
    {
       // irgendein statement das einen Zähler wie ct braucht
       ++ct;
    }
    

    ==>

    for( auto iter = ... ; ... ; ...) count( int ct; )
       // irgendein statement das einen Zähler wie ct braucht
    

    Oder

    for count( int ct; 0 ; 10 ) // Bemerkung von oben.
        std::cout << ct << " bottles of beer ... ";
    

    (Sorry für das eklige Latex 😃 )

    Edit: Wenn die Idee nicht totaler Blödsinn ist, dann, so fällt mir gerade auf, sollte das ein Mod vielleicht splitten. 💡 (oder?)

    Naja, mit C++11 gibt es ja jetzt noch weitere schleifen, gerade for( : ) ist ganz nett.
    Aber bei auto in for für den Zähler kann es dir passieren, das du ein int statt size_t bekommst:

    vector<int> vec = fill();
    for(auto i = 0; i < vec.size(); ++i)
        cout << vec[i];
    

    Auch müsste man dann die Schrittgröße (default 1) angeben.
    Ich halte aber weder von deiner Idee noch von der if-schleife etwas. Das müllt die Sprache zu, ohne wirkliche Vorteile zu bringen.



  • Ich halte aber weder von deiner Idee noch von der if-schleife etwas. Das müllt die Sprache zu, ohne wirkliche Vorteile zu bringen.

    So eine radikale Sicht auf Features dieser Art halte ich für polemisch. Es ist allgemein bekannt das einige Features, darunter Range-Based For, eben einfach nur Syntax-Zucker sind, bzw. kein Problem lösen.
    Trotzdem sind die Leute davon angetan. Es geht eben darum, dass man die Sprache lesbarer und angenehmer zu schreiben gestaltet. Dabei helfen dinge wie auto *, oder eben eine loop-counter expansion.

    *'s gibt auch Fälle wie trailing return types, wo es coole Combos mit Templates gibt, da beklage ich mich nicht 🕶 👍



  • Hmm, es wäre genial gewesen, Tuple in den Sprachkern einzubauen:

    (string, int, int) kontodaten()
    {
        return ("Müller", 123, 456789);
    }
    
    ...
    
    auto name, nr, blz = kontodaten();
    
    oder
    
    auto daten = kontodaten();
    auto name, nr, blz = daten;
    name = daten[0]
    

    Syntax ist so natürlich Käse da ziemlich doppeldeutig, aber ich fände das Feature schön und es wäre sehr leicht umzusetzen.



  • int ct = 0; 
    for( auto iter = ... ; ... ; ... ) 
    { 
       // irgendein statement das einen Zähler wie ct braucht 
       ++ct; 
    }
    

    Nun, man kann ct immerhin in den Schleifenkopf aufnehmen.

    for( auto iter = ... ; ... ; ... , ++ct) 
    { 
       // irgendein statement das einen Zähler wie ct braucht 
    }
    

Anmelden zum Antworten