C++09 (Teil 1) - Ein Überblick: Sprachfeatures



  • Viele Sprachfeatures (vorallem die Variadic-Templates, Concepts) werden eher für Library-Entwickler interessant sein. Und das sind eigentlich auch die (meiner Meinung nach) komplexeren neueren Features. Viele C++-Einsteiger werden eher Anwendungen entwickeln und nicht eine Library. D.h. sie werden sich mit den komplexeren Themen garnicht auseinander setzen müssen. Das ist ja auch heute schon so mit den Templates. Als Anfänger benutzt man doch eher fertige Templates aus der Std-Library und das ist doch recht einfach, oder? Und hier machen die Concepts es sogar noch einfacher für einen Template-Anwender, weil er bei einer Falschbenutzung verständlichere Fehlermeldungen erhält.

    Irgendwann wird der nächste Step für einen Template-Anwender sein, das er vielleicht selber Templates und somit Libraries entwickelt. Dann wird er natürlich auf die vielen Features stossen. Gut, er wird natürlich viel lernen müssen. Aber auch nicht alles auf einmal. Es ist ja immer ein Lernprozess dahinter.

    Übrigens, ich sehe es eigentlich nüchtern: andere Sprachen haben weniger Sprachfeatures ggü. C++, aber sie gleichen das mit viel Tools und Frameworks wieder aus. Und diese muß man ja auch lernen. Wir benutzen hier auf Arbeit die OSGi und Eclipse Platform, da wird das Classloading u.ä. total anders gehandhabt, als in der Standard-Java-Runtime. Es ist also eine Erweiterung an der Basis, wenn auch nicht an der Sprache. Jemand der Java kann, muß diese Erweiterung von OSGi und Eclipse ebenfalls zusätzlich lernen, um in unseren Projekten mitarbeiten zu können. Aber lernen muß man immer. Im C++09 wirds halt die Features in der Sprache geben.



  • Artchi schrieb:

    Gut, er wird natürlich viel lernen müssen. Aber auch nicht alles auf einmal.

    so wie ein chinese seine ca. 90000 schriftzeichen. 😃
    🙂



  • Und C++ wird nicht komplexer. die neuen features sind allesamt Lösungen für Hacks die in der vergangenheit verwendet wurden.
    Variadic templates sind endlich eine Lösung für probleme die bislang mit Preprocessor librarys gelöst werden mussten. Halt der Klassische Fall: eine funktion für 0-n argumente. Und der hack ist wesentlich komplizierter als Variadic templates.



  • otze schrieb:

    die neuen features sind allesamt Lösungen für Hacks die in der vergangenheit verwendet wurden.

    aber die alten hacks bleiben allesamt erhalten, oder?
    🙂



  • Nö, die kannst du ja jetzt durch die neuen Sprachfeatures ersetzen.



  • Vielen Dank für den Artikel, ich habe noch eine Frage: Wieso hast du nichts zu dem Garbage-Collector geschrieben, der ja wenigstens geplant war? Wird der im endgültigen Standard doch nicht enthalten sein (hoffentlich :D) oder hat das andere Gründe?

    Felix



  • In C++09 wird der soweit ich weiß nicht drin sein.



  • Weiß jemand, welche Art GC für C++ angedacht ist? Sollte es dann wie in C++/CLI dafür eigene Pointer-Typen geben, oder würde es sowas wie der Boehm Collector (= konservativ) werden? Sorry, falls es zu offtopic wird, ich frage dann auch nicht mehr genauer nach. Mich interessiert das Thema GC nur generell.

    Btw. sehe ich grad noch die verbesserten for-loops. Ich bin froh, dass es das jetzt auf Sprachebene geben wird. Das mit den Makros ist einfach nichts gescheites.



  • Der GC ist vom Komitee zurückgestuft worden, weil da einfach noch zu viel unklar ist. Nix mit 09 also.
    Das Komitee schreibt dazu:

    A second proposed compromise to meet the timetable is the scaling back of the garbage collection feature. It is planned to remove known problems that inhibit garbage collected implementations, without actively designing a new feature.

    d.h., das ist alles, was in C++09 drin sein wird.

    Ein GC also entweder in einem späteren Standard oder als Technical Report.

    Optimizer schrieb:

    Weiß jemand, welche Art GC für C++ angedacht ist? Sollte es dann wie in C++/CLI dafür eigene Pointer-Typen geben, oder würde es sowas wie der Boehm Collector (= konservativ) werden? Sorry, falls es zu offtopic wird, ich frage dann auch nicht mehr genauer nach. Mich interessiert das Thema GC nur generell.

    C++/CLI wird im letzten (zurückgestuften) Proposal *nicht* empfohlen. Es ist angedacht, Programme voll unter die Kontrolle eines GCs zu stellen (wobei das optional (bzw. "programmer-directed") aktiviert werden soll, wo auch z.B. ints nach Adressen auf Objekte untersucht werden sollen (zumindest, wenn man sie als gc_relaxed deklariert).
    Aber H. Boehm kann das in seinem Proposal sicher besser als ich zusammenfassen.

    AFAIR geht die Syntax für ein new ohne GC dann so:

    new (nogc) X;
    //und
    malloc_nogc
    

    Es wird dann auch möglich sein, das ganze auf der Ebene von Übersetzungseinheiten zu steuern. Mit einem

    gc_forbidden;
    

    wird der GC abgeschaltet (für die eine Unit), auch ein Objekt gc_lock lock; kann per RAII für eine einzelne Funktion den GC unterbinden.

    Ich habe das aber weder hier noch im nächsten Artikel angesprochen, weil es eben nicht Teil von 09 sein wird.

    Achja: Der GC wird *keine* Destruktoren aufrufen, auch kein finally ist angedacht.



  • Danke. 🙂



  • Wozu auch nen GC? Jeder C++ Programmierer ist es doch gewohnt ohne zu Leben und weiß damit umzugehen (smart-ptr), von daher sehe ich da keinen Vorteil den in den Standard aufzunehmen und GC-Bibliotheken gibt es ja bereits für die die es dennoch brauchen.

    Mir gefallen die Ideen der neuen Konzepte sehr gut, aber deren Syntax gefällt mir zum Großteil weniger 😕



  • Wenn jemand gerne über das Thema "GC in C++XY" dann soll er bitte ein Topic in RudP eröffnen.



  • Schöner Artikel 🙂 👍

    Ne Frage: Wieso kann man decltype nicht erweitern, um es folgendermaßen benutzen zu können:

    decltype(int + double); // Kann das ein Ausruck sein ? Müsste man den Standard bissl umschreiben ;)
    

    Das müsste sich doch leicht machen lassen, dann würde man auch Funktionen leicher deklarieren können:

    template<class A, class B>
    decltype(A + B) operator+( const A& a, const B& b);
    

    Und wenn nicht könnte man sich die "komplizierte" Funktionsdeklaration sparen, indem man decltype in Kombination mit T() benutzt, dann hätte man wieder seinen normalen Ausdruck:

    template<class A, class B>
    decltype(A() + B()) operator+( const A& a, const B& b);
    

    Alle Build'ins haben (), natürlich müsste T dieses dann auch bereitstellen ...



  • ... Ist decltype überhaupt nen Compile-Zeit-Operator ?



  • KasF schrieb:

    ... Ist decltype überhaupt nen Compile-Zeit-Operator ?

    Muss es, da C++ ein statisches Typsystem hat.



  • Prokkramierer schrieb:

    Muss es, da C++ ein statisches Typsystem hat.

    Stimmt ja 🙂

    Was ist mit dem Trick nun:

    template<class A, class B>
    decltype(A() + B()) operator+( const A& a, const B& b);
    

    anstatt:

    template<class A, class B>
    auto operator+( const A& a, const B& b) -> decltype(a + b);
    

    Kann das funktionieren ?



  • KasF schrieb:

    Was ist mit dem Trick nun:

    template<class A, class B>
    decltype(A() + B()) operator+( const A& a, const B& b);
    

    Ich würde mal aus dem Bauch heraus sagen, das funktioniert ohne Probleme, wenn A und B default-konstruierbar sind.



  • KasF schrieb:

    [Was ist mit dem Trick nun:

    template<class A, class B>
    decltype(A() + B()) operator+( const A& a, const B& b);
    

    Kann das funktionieren ?

    Daran ist nichts auszusetzen - aber ist das wirklich einfacher?
    Die andere Deklarationsform erlaubt es, den typbestimmenden Ausdruck genauso zu schreiben, wie er dann tatsächlich in der Implementation vorkommt - bei traditioneller Schreibweise wie hier sieht das dagegen doch recht umständlich aus (insbesondere wenn die Funktionsparametertypen komplexer werden (häufig genug werden die ja irgendwie komplex aus den Templateparametern zusammengesetzt).
    Was ich evtl. kritisieren würde, ist, dass auch bei neuer Schreibweise immer noch Codeduplizität auftritt - der decltype-Ausdruck nimmt ja im Grunde die Implementation vorweg. So gesehen wäre es ggf. wünschenswert, den return-Typ gar nicht explizit angeben zu müssen und auf diesen aus der Implementation zu schließen, z.B.:

    template<typename T, typename U>
    constexpr auto max(T&& a, U&& b) { return a < b ? b : a; } // implizit inline auch ohne constexpr, statt
    template<typename T, typename U>
    constexpr auto max(T&& a, U&& b) -> decltype( a < b ? b : a ) { return a < b ? b : a; }
    

    Das wäre denkbar, wenn die Implementation wie bei contexpr dann vornherein auf ein einzelnes return-Statement beschränkt ist (die meisten Fälle, die mir einfallen, sollten sowieso constexpr sein). Ist aber wahrscheinlich nicht wichtig genug, um die Sprache dafür zu ändern.



  • Bashar schrieb:

    KasF schrieb:

    Was ist mit dem Trick nun:

    template<class A, class B>
    decltype(A() + B()) operator+( const A& a, const B& b);
    

    Ich würde mal aus dem Bauch heraus sagen, das funktioniert ohne Probleme, wenn A und B default-konstruierbar sind.

    oder man würde auf nummer sicher gehen:

    template <class A, class B>
    decltype(*static_cast<A*>(0) + *static_cast<B*>(0)) operator + (A const&, B const&);
    

    das ist umständlich.

    camper schrieb:

    Was ich evtl. kritisieren würde, ist, dass auch bei neuer Schreibweise immer noch Codeduplizität auftritt - der decltype-Ausdruck nimmt ja im Grunde die Implementation vorweg. So gesehen wäre es ggf. wünschenswert, den return-Typ gar nicht explizit angeben zu müssen und auf diesen aus der Implementation zu schließen, z.B.:

    template<typename T, typename U>
    constexpr auto max(T&& a, U&& b) { return a < b ? b : a; } // implizit inline auch ohne constexpr, statt
    template<typename T, typename U>
    constexpr auto max(T&& a, U&& b) -> decltype( a < b ? b : a ) { return a < b ? b : a; }
    

    ich habe dunkel in erinnerung, diesen vorschlag irgendwo gelesen zu haben. ein schnelles durchschauen der passenden dokumente hat aber jetzt irgendwie nichts gebracht. ich wüsste jetzt aber nicht einmal mehr, wie weit ausgereift dieser vorschlag wäre.



  • camper schrieb:

    aber ist das wirklich einfacher?

    Kommt wahrscheinlich auf die Funktion an. Bei op+ zb sind mir ja die Parameter egal, mich interessiert ja nur der Typ. Hingegen bei deinem max müsste ich die auto -> decltype Variante benutzen.

    Wobei ich auto -> decltype irgendwie schöner finde, also decltype( T()+U() ) 🙂

    camper schrieb:

    Was ich evtl. kritisieren würde, ist, dass auch bei neuer Schreibweise immer noch Codeduplizität auftritt - der decltype-Ausdruck nimmt ja im Grunde die Implementation vorweg.

    Hmmm, das gefällt mir irgendwie gar nicht, wäre schön wenn das so Umgesetzt werden könnte, wie du es vorgeschlagen hast.


Anmelden zum Antworten