Was sind eure Highlights von C++14?



  • otze schrieb:

    Warum? VLAs liegen auf dem Stack, im Gegensatz zu array oder vector.

    auch std::array liegt komplett auf dem "Stack".

    Laut http://en.cppreference.com/w/cpp/container/array
    ist std::array vergleichbar mit einem struct, welches ein C-Array mit fester länge enthält.

    Und zu mindestens die Implementation von std::array im gcc 4.6.3 enthält kein
    new um platz für die Elemente zu bekommen.



  • auch std::array liegt komplett auf dem "Stack".

    Das ist offensichtlich. std::array ist nur ein Wrapper um ein echtes Array.

    Ein Swap-Operator würde übrigens automatisch ADL einbinden. 😉



  • Keine neuen Operatoren für irgendwelche herkömmlichen Funktionen, was soll so was? C++ ist kryptisch genug, bald programmiert das keiner mehr, weil's zu verworren aussieht und stirbt aus, genial. Absolut für die Anti-Swap-Operator-Bewegung. Da fände ich einen Move-Operator noch sinnvoller, aber auch das finde ich schwachsinnig...

    vector<string> vec1, vec2;
    // fill vec1
    vec2 ä vec1;
    

  • Mod

    otze schrieb:

    TyRoXx schrieb:

    Das VLA ist der letzte Sargnagel für C-Arrays. Jetzt kann man versehentlich eine Variable als Länge angeben.

    Warum sollte das schlecht sein?

    Wenn ich das richtig verstehe, können VLA-Definitionen std::bad_array_length werfen. Da nehme ich doch lieber array oder vector .

    Warum? VLAs liegen auf dem Stack, im Gegensatz zu array oder vector. Das ist groß-ar-tig. 0 overhead, automatisch augeräumt und unglaublich nützlich. Ich habe VLAs ab dem Moment vermisst, als ich reduce operatoren mit OpenMP implementieren wollte für die ich ein kleines array - größe anzahl der threads (dynamisch) brauche. std::array ist umständlich und std::vector spürbarer overhead.

    Ich verstehe nicht, wieso der Sprachkern für so ein Feature geändert werden muss. Eine Librarylösung würde es auch tun (dass dafür zusätzliche Compilermagie benötigt wird, ist unwesentlich).



  • camper schrieb:

    Ich verstehe nicht, wieso der Sprachkern für so ein Feature geändert werden muss. Eine Librarylösung würde es auch tun (dass dafür zusätzliche Compilermagie benötigt wird, ist unwesentlich).

    Die C99-Kompatibilität finde ich nicht schlecht. Mich stört nur der unnötige Check zur bad_array_length, das wäre die Aufgabe einer Librarylösung. Schön wäre auch eine Librarylösung, die keine Exception wirft, sondern auf den Heap zurückgreift, wenn der Stackspeicher nicht ausreicht.



  • Jens Weller hat anscheinend in seiner Artikel-Serie auch viele Porposals verarbeitet, die nicht im C++14 Entwurf gelandet sind. Mir stellt sich die Frage, was davon wirklich im C++14 Entwurf gelandet ist. Ist dies hier eine vollständige Liste der "core language features"?

    Und dann gibt's in der Standardbibliothek natürlich mindestens noch make_unique als neues Feature. Was noch? Sind die Typ-Transformations-Aliase auch dabei?

    Das mit der gnädigeren Deduktion für Funktionsrückgabetypen finde ich gut.
    Polymorphe Lambdas sind auch nicht schlecht.
    make_unique ist nett.
    Und diese Typ-Transformations-Aliase wären auch nett.
    Die flexiblere Capture-Clause für Lambdaausdrücke ist auch gut. Fand ich damals schon ziemlich blöd, dass es kein "move capture" gab.

    Die VLAs find ich irgendwie blöd und ich weiß auch nicht, was ich von dyn_array halten soll. Wo ist jetzt noch der Sinn von dyn_array, wenn es VLAs gibt? Konnten die sich nicht entscheiden? ein dyn_array ist natürlich wieder nicht move-bar. Na supi. Ich verstehe nicht, was das alles soll.

    BTW: Habe gerade gesehen, dass hier auch ein paar C++14 Bibliotheks-Features auftauchen.


  • Mod

    speckarray schrieb:

    camper schrieb:

    Ich verstehe nicht, wieso der Sprachkern für so ein Feature geändert werden muss. Eine Librarylösung würde es auch tun (dass dafür zusätzliche Compilermagie benötigt wird, ist unwesentlich).

    Die C99-Kompatibilität finde ich nicht schlecht.

    Gemessen daran, was alles (zum Glück) nicht unterstützt wird, bleibt da nicht viel Kompatibilität übrig.



  • Sind die Typ-Transformations-Aliase auch dabei?

    Ja.

    Wo ist jetzt noch der Sinn von dyn_array, wenn es VLAs gibt?

    👎 Was ist der Sinn von** std::array **, wenn es schon richtige Arrays gibt? Und std::array hat natürlich genauso wenig Move-Semantik wie dynarray ...

    Ich verstehe nicht, wieso der Sprachkern für so ein Feature geändert werden muss. Eine Librarylösung würde es auch tun (dass dafür zusätzliche Compilermagie benötigt wird, ist unwesentlich).

    So sehe ich das auch. Der Standard kann dabei sogar die storage duration-Klasse offen lassen*. Das wäre bei VLAs allerdings nicht so flexibel... der sizeof -Operator darf auf sie nicht angewandt werden (Größe muss separat gespeichert werden, auch wenn das in den meisten Fällen automatisch passiert), als Member kann man die Größe nicht im Konstruktor festlegen...
    (Edit: Über letzteres bin ich mir gerade im Unklaren)

    *Klar, dass das - wo möglich und sinnvoll - auf den Stack gepackt wird.



  • Sone schrieb:

    Was ist der Sinn von** std::array **, wenn es schon richtige Arrays gibt?

    Richtig: es gibt keinen.



  • Das ist so furchtbar lächerlich. Wenn ein Feature überhaupt keine Daseinsberechtigung hat, wäre es schon längst als deprecated markiert (oder überhaupt nicht erst aufgenommen worden).

    Mich stört nur der unnötige Check zur bad_array_length, das wäre die Aufgabe einer Librarylösung.

    Ich finde, der ist gerechtfertigt. VLA-Elemente sollen auf dem Stack landen. Daher ist diese Klausel

    If the size of the array exceeds the size of the memory available for objects with automatic storage duration, the behavior is undefined.
    [Fußnote:]Implementations that detect this case are encouraged to throw an exception that would match a handler of type std::bad_array_length

    in meinem Interesse.

    Schön wäre auch eine Librarylösung, die keine Exception wirft, sondern auf den Heap zurückgreift, wenn der Stackspeicher nicht ausreicht.

    Wenn es dir sowieso nicht wichtig ist, wo deine Objekte landen, was du schließlich suggerierst, nimm gleich std::vector !
    In welcher Situation ist man von der storage duration nicht abhängig, hat aber einen Vorteil wenn die Elemente auf dem Stack landen?



  • Sone schrieb:

    In welcher Situation ist man von der storage duration nicht abhängig, hat aber einen Vorteil wenn die Elemente auf dem Stack landen?

    Einfach süß 👍



  • knivil schrieb:

    Resumable functions: Na hoffentlich wird das von Compilern nicht über Context-Switching implementiert.

    Wenn Resumable Functions aehnlich Coroutines sein sollen, dann gibt es unter Linux nur die Moeglichkeit es mittels Threads zu loesen, da andere Betriebssystemfunctionen wie setcontext als deprecated markiert sind.

    Man kann die Funktion auch einfach in eine State-Maschine transformieren, so wie das ein C# Compiler mit async/await auch macht. Das hat dann gar keinen Overhead.

    Edit: Mal abgesehen davon, dass setcontext für Context-Switching gar nicht mal nötig ist. Das kann man problemlos mit Assembler machen, siehe z.B. boost.context.



  • N3574 - Binding stateful functions as function pointers

    Wäre der Hammer! 🙂



  • /blitzmerker/ schrieb:

    Sone schrieb:

    In welcher Situation ist man von der storage duration nicht abhängig, hat aber einen Vorteil wenn die Elemente auf dem Stack landen?

    Einfach süß 👍

    Das ist ja Blödsinn. Nein, der Stack ist ja performanter, hab' ich wieder außen vorgelassen. Kopf->Tisch.



  • Sone schrieb:

    Ich habe immer noch dieselbe Meinung darüber - prinzipiell nur Syntaxzucker, nichts weiter. Trotzdem mag ich es und es hätte mich gefreut, würde es angenommen werden.

    Ne, :=: wäre idiotisch. Heute ist man soweit, dass man beim Ausdruck swap(a, b) mit ADL schon sehr viele swap-Funktionen tatsächlich aufrufen kann. Käme hier :=: dazu, hat man für die genau gleiche Funktionalität völlig unnötigerweise zwei verschiedene Schreibweisen und hätte mehr Mühe, generischen Code zu schreiben.

    Manchmal überlegen sich Leute rein gar nichts, wenn sie Proposals liefern.

    krümelkacker schrieb:

    und noch ein using std::swap; davor, damit auf std::swap zurück gefallen werden kann, wenn es keine spezielle Version für einen bestimmten Typen gibt, die per ADL auffindbar ist.

    Oder:

    template <typename T>
    void adl_swap(T& lhs, T& rhs)
    {
        using namespace std;
        swap(lhs, rhs);
    }
    

    Vielleicht noch perfect forwarden. using namespace std statt using std::swap deswegen, weil die swap-Funktion dann zu dem Zeitpunkt noch nicht deklariert sein muss. Oder muss sie das ohnehin?

    Ethon_ schrieb:

    N3574 - Binding stateful functions as function pointers

    Gehts hier um Lambdas mit Variablen in der Capture-List? Falls ja, wie soll das vernünftig implementiert werden?

    <💡>


  • Mod

    glühbirne schrieb:

    using namespace std statt using std::swap deswegen, weil die swap-Funktion dann zu dem Zeitpunkt noch nicht deklariert sein muss. Oder muss sie das ohnehin?

    Das ergibt keinen Sinn. Eine Deklaration innerhalb des Templates ist nicht erforderlich, und wenn man viel Glück hat enthalten umliegende Namensräume keine swap-Deklarationen, die keine Funktionen sind. Falls doch, hat man ein Problem, dann ist das kein Funktionsaufruf mehr (jedenfalls nicht der einer Funktion namens swap, sondern ggf. ein Konstruktoraufruf (Typ gefunden), oder ein Aufruf eines überladenen ()-Operators (Objekt mit Namen swap)) - und dann findet auch kein ADL bei der Instantiierung statt. Also ist es besser, eine swap-Deklaration im Scope zu haben, die garantiert eine Funktion deklariert.



  • Sone schrieb:

    Was ist der Sinn von** std::array **, wenn es schon richtige Arrays gibt?

    Wo ist der Sinn von VLAs wenn's doch std::dynarray gibt? Aber im Vergleich zu rohen Arrays und std::array bietet die Präsenz von VLA als auch dynarray eine gewisse Konsistenz bzgl. zwei Mittel für eine Sache anzubieten. Supi. Ich weiß nicht, kommt mir halt doppelt-gemoppelt vor. rohe Arrays und std::array ist ja nur so gewachsen. Ist das Grund genug, VLAs zusätzlich zu dynarray anzubieten?



  • Kellerautomat schrieb:

    Man kann die Funktion auch einfach in eine State-Maschine transformieren, so wie das ein C# Compiler mit async/await auch macht. Das hat dann gar keinen Overhead.

    Ich wuerde im ersten Schritt auf bekanntes abbilden, genau wie std::thread auf POSIX-Threads unter Linux aufbaut anstatt die entsprechenden syscalls zu benutzen. Desweiteren sehe ich Probleme, wenn ein yield innerhalb von verschachtelten Schleifen oder rekursive Funktionen aufgerufen wird. Ein endlicher Automat wird nicht ausreichen.

    Edit: Mal abgesehen davon, dass setcontext für Context-Switching gar nicht mal nötig ist. Das kann man problemlos mit Assembler machen, siehe z.B. boost.context.

    Man kann alles mit Assembler machen. What's the point?



  • glühbirne schrieb:

    Ethon_ schrieb:

    N3574 - Binding stateful functions as function pointers

    Gehts hier um Lambdas mit Variablen in der Capture-List? Falls ja, wie soll das vernünftig implementiert werden?

    <💡>

    Jap, so ähnlich - zb. um Lambdas mit Capture-List als C-Funktionszeiger verwenden zu können. Die einzige Möglichkeit die mir einfällt:

    Dynamisch zur Laufzeit einen ausführbaren Speicher allozieren und da (Assembler) Code reinschreiben, der die C-Calling Convention respektiert, die Parameter entgegennimmt und das Funktionsobjekt mit ihnen aufruft.

    Ist mit libffi closures ganz easy machbar, libffi übernimmt den ganzen Lowlevel-Kram.



  • krümelkacker schrieb:

    Cyres schrieb:

    Frage_Swap schrieb:

    Wie würde man sowas machen, also ohne den Operator?

    swap(a, b)
    

    und noch ein using std::swap; davor, damit auf std::swap zurück gefallen werden kann, wenn es keine spezielle Version für einen bestimmten Typen gibt, die per ADL auffindbar ist.

    und noch ne Klasse, und noch Member, und noch ne Methode und und und... 🙄


Anmelden zum Antworten