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



  • 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 
    }
    


  • Sone schrieb:

    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 🕶 👍

    Ich mag diese was-wäre-wann Syntax-meta Diskussionen nicht. Hinzu kommt, dass du bei den Sprachfeatures wiederum auf die Compilerhersteller angewiesen bist, C++ ist ja nicht wie java oder .net wo es nur einen Hersteller für die Plattform gibt.
    Und gerade bei sowas trivialem wie countern verstehe ich nicht, dass man die Sprache erweitern muss.
    Bei if-for frage ich mich, wieso man dies a) auf for beschränkt und b) wie man dies sinnvoll in die Syntax der Sprache einbaut.

    Für mich ist erstmal wichtig, dass sie mit C++14 die Standard Library sinnvoll erweitern und C++11 näher an den ursprünglich geplanten Umfang bringen. Evtl. noch kleinere Spracherweiterungen, concepts lite wäre nett, aber da muss man das Treffen in Bristol abwarten.
    Da habe ich von einem Committee member die Auskunft das es wohl nicht in C++14 schaffen wird (This concepts lite thing, looks nice. Any chance for C++14 for it? -> "almost none"), andererseits kann man in den Meeting Minutes von März für concept lite lesen, dass sie sehr wohl überlegen, wie sie zumindest einen Teil davon schon in C++14 bringen können. Das müsste man dann im Herbst in Chicago oder zwischen Bristol und Chicago sehen.



  • Ethon schrieb:

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

    (string, int, int) kontodaten()
    {
        return ("Müller", 123, 456789);
    }
    

    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.

    Gab letztes Jahr auf der C++Now einen interessanten Vortrag zu Tuple, und wie es aktuell umgesetzt ist.
    Ich bin mir immer noch nicht sicher, ob die einfachheit und eleganz von tuple den Aufwand bei der Kompilierung rechtfertigt.
    Gerade wenn man Funktionen wie apply_tuple und die Umsetzung davon sieht.

    Siehe: http://www.metaxcompile.com/blog/2013/03/16/Working_with_tuples.html und die folgenden Blogartikel darüber.



  • Auf reddit wurde für if-for nun folgende Library-lösung vorgeschlagen:

    namespace std {
    template <class Range, class Function>
    auto for_while(Range& range, Function func) -> std::pair<decltype(std::begin(range)), bool>
    {   
        auto it = std::begin(range);
        auto endit = std::end(range);
    
        for (; it != endit; ++it)
        {   
            if (!func(*it)) break;
        }   
    
        return std::make_pair(it, it == endit);
    }   
    } // namespace std {
    
    int main()
    {   
        std::vector<int> v{1, 2, 3}; 
        auto r = std::for_while(v, [](int i)
        {   
            // do something with i;
            return false; // or false to break.
        }); 
    
        if (r.second)
        {   
            std::cout << "all done" << std::endl;
        }   
        else
        {   
            std::cout << "break early: " << *r.first << std::endl;
        }   
    }
    

    Eigentlich recht elegant finde ich.



  • Sone schrieb:

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

    Ich würde versuchen, es anders lösen. In etwa so:

    vector<long> foo = {2,3,5,7,11,13,17,19};
    for (auto p : foo|counted) {
      cout << p.first << ": " << p.second;
    }
    

    wobei die Syntax dann in Richtung Pipe/Range-Adapter geht. Das bekommt man auch ohne Sprachkernerweiterung hin. Ich denke mal, p sollte hier sowas wie ein std::pair<size_t,long&>-Objekt sein, wobei hier first der Index sein soll und second sich auf dasselbe bezieht wie die vector<long>-Iterator-Dereferenzierung.

    Ich bin jedenfalls dafür, dass ein paar "Range-Adapter" hinzukommen, nicht nur so'was wie "counted".



  • So, Part4 ist fertig, und damit auch alle Papers des pre-Bristol Mailings behandelt:
    http://www.meetingcpp.com/index.php/br/items/a-look-at-c14-and-beyond-papers-part-4.html



  • krümelkacker schrieb:

    Sone schrieb:

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

    Ich würde versuchen, es anders lösen. In etwa so:

    vector<long> foo = {2,3,5,7,11,13,17,19};
    for (auto p : foo|counted) {
      cout << p.first << ": " << p.second;
    }
    

    wobei die Syntax dann in Richtung Pipe/Range-Adapter geht. Das bekommt man auch ohne Sprachkernerweiterung hin. Ich denke mal, p sollte hier sowas wie ein std::pair<size_t,long&>-Objekt sein, wobei hier first der Index sein soll und second sich auf dasselbe bezieht wie die vector<long>-Iterator-Dereferenzierung.

    Ich bin jedenfalls dafür, dass ein paar "Range-Adapter" hinzukommen, nicht nur so'was wie "counted".

    http://ideone.com/zlqKs1

    Ist jetzt nur schnell zusammengeschrieben mit viel Luft nach oben 🤡
    Man könnte dem iterator noch ein paar Methoden spendieren und die Klasse für " const Range " nutzbar machen. Aber ich denk das Prinzip ist klar 😉


Anmelden zum Antworten