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



  • Das mit den Modulen hab ich hier her:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/#mailing2007-12
    Den genauen Entwurf von Vandevoorde findest du hier:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2316.pdf (inzwischen Revision 5)



  • Cool, danke für die Links! Muss mich erstmal durch die 23 Seiten durcharbeiten, aber oberflächlich sieht's schonmal nett aus 👍



  • Eine Anmerkung:
    Sollte man das Beispiel:

    int foo ();
    auto x2 = foo();
    auto const& x3 = foo(); //auto kann mit cv-Qualifizierern, * und & verwendet werden
    

    nicht besser so umschreiben, dass x3 keine Referenz auf eine temporäre Variable ist?

    Vielleicht einfach

    auto const& x3 = x2;
    


  • C++09 schrieb:

    Die Netzwerkbibliothek war ja wirklich notwendig. Eigentlich nicht so schön das es noch dauert.
    Mit Modulen meine ich das Paper von David Vandervoorde. Es gab Pläne es mit einem dynamischen Modulsystem (Plugins) zu kombinieren, so wie ich mitbekommen habe. Die Einschnitte in den C++ Standard sind aber wahrscheinlich zu groß als das man hier schnell etwas sehen wird. Denn das bedeutet faktisch die Anbschaffung des alten auf #include-Anweisungen basierenden Modulariesierungssystems - wenn man das überhaupt so nennen konnte 😉 -. Aber interessant wäre es schon. Das würde Compilezeiten drastisch reduzieren, Namespace pollution
    vermeiden und Sachen wie Whole Program Optimisation für Compiler Entwickler deutlich vereinfachen.
    Scheinbar interessieren sich aber viele dafür weil es schon oft einem Peer-Review unterzogen wurde und in einen nachfolgenden TR aufgenommen werden soll, zumindest laut www.open-std.com

    Ich bezweifle, dass es die Sache für Compilerentwickler vereinfachen wird, da sie den alten Mist trotzdem unterstützen müssen. Aber die Programmierer werden davon natürlich profitieren, weil neue Libs u.U. dieses Feature dann nutzen. Die Compilerbauer tun mir echt langsam leid. Es kommt immer neues freakiges Zeug hinzu, dabei ist offensichtlich, dass sie jetzt schon überfordert sind. 😞

    Ich freue mich jedenfalls trotzdem darauf. 🙂 Ich hoffe, dass zumindest für den nächsten Standard die Concepts noch kommen.



  • Optimizer schrieb:

    Die Compilerbauer tun mir echt langsam leid. Es kommt immer neues freakiges Zeug hinzu, dabei ist offensichtlich, dass sie jetzt schon überfordert sind. 😞

    Warum votieren sie dann nicht dagegen? Der Standardisierungsprozess läuft ja nicht gerade hinter verschlossenen Türen ab.



  • Naja ich rede von den Code-Sklaven, die im -87ten Stock im Microsoft-Campus eingesperrt sind. 🤡 Das sind nicht die Leute, die offiziell die Position vom MS (insert beliebige Firma here) vertreten. Überhaupt bin ich mir nicht sicher, ob sie die Änderungen ablehnen würden - ich sag nur, sie tun mir leid.



  • Bashar schrieb:

    Optimizer schrieb:

    Die Compilerbauer tun mir echt langsam leid. Es kommt immer neues freakiges Zeug hinzu, dabei ist offensichtlich, dass sie jetzt schon überfordert sind. 😞

    Warum votieren sie dann nicht dagegen? Der Standardisierungsprozess läuft ja nicht gerade hinter verschlossenen Türen ab.

    Weil die Veränderungen ihre Arbeitstelle sichert 😃



  • UTF-16-String-Literale. Eingeleitet werden diese mit dem Präfix u. Die dahinterstehende Kodierung ist UTF-16 und der Typ der Literale ist "Array von n const char16_t". char16_t ist ein neu eingeführter Typ mit der Kodierung UTF-16, der im Header <cuchar> definiert ist.

    Wollte fragen, ob ich mir mit diesem Typ die Konvertierung sparen kann? D.h. wenn ich UTF-16 Daten mit komplexen Zeichen einlese, konvertiert mir char16_t die Daten automatisch nach UTF-16?

    Bis wann genau werden die gesamten Erneuerungen zur Verfügung stehen? Und wie sieht es aus mit "Polymorphic Function Objects" welche im TR1 beschrieben sind. Bis wann wird man diese Erneuerungen nutzen können?

    Dann wollte ich noch fragen, ob es irgendwelche Erneuerungen bezüglich Objekte zeichnen gibt. Also ob es ander Möglichkeiten gibt um eine Linie oder ein Rechteck zu zeichnen - also ein Kollege meinte, dass es Erneuerungen gibt bzw. geben wird, aber ich habe noch nicht wirklich etwas darüber gefunden! Wäre super wenn ihr mir weiterhelfen könntet!



  • Warum sollten wir etwas dagegen haben? Wir bekommen ja schließlich Geld dafür :p



  • sinamine schrieb:

    UTF-16-String-Literale. Eingeleitet werden diese mit dem Präfix u. Die dahinterstehende Kodierung ist UTF-16 und der Typ der Literale ist "Array von n const char16_t". char16_t ist ein neu eingeführter Typ mit der Kodierung UTF-16, der im Header <cuchar> definiert ist.

    Wollte fragen, ob ich mir mit diesem Typ die Konvertierung sparen kann? D.h. wenn ich UTF-16 Daten mit komplexen Zeichen einlese, konvertiert mir char16_t die Daten automatisch nach UTF-16?

    ich weiß jetzt leider nicht aus dem stehgreif, ob es standard-streams gibt, die daten automatisch als UTF-16 einlesen können (basic_iostream<char16_t>), aber im prinzip stünde dem nichts im wege. char16_t werden eben, ganz un-standard-mäßig gesprochen, 2-byte-oder-mehr-character sein, die für UTF-16 ausreichend platz bieten, mehr nicht.

    Bis wann genau werden die gesamten Erneuerungen zur Verfügung stehen? Und wie sieht es aus mit "Polymorphic Function Objects" welche im TR1 beschrieben sind. Bis wann wird man diese Erneuerungen nutzen können?

    bis wann? die sachen, die im TR1 beschrieben sind, werden beinahe wortwörtlich in den neuen standard übernommen werden. die funktionen rund um std::bind sind durch boost schon seit langem verfügbar und werden eben obligatorisch.

    Dann wollte ich noch fragen, ob es irgendwelche Erneuerungen bezüglich Objekte zeichnen gibt. Also ob es ander Möglichkeiten gibt um eine Linie oder ein Rechteck zu zeichnen - also ein Kollege meinte, dass es Erneuerungen gibt bzw. geben wird, aber ich habe noch nicht wirklich etwas darüber gefunden! Wäre super wenn ihr mir weiterhelfen könntet!

    hm. andere möglichkeiten? bis jetzt hat der standard nicht definiert, was linien oder rechtecke sind, d.h. du wirst bis jetzt immer irgendein toolkit verwendet haben, das diese funktionen zur verfügung stellt.
    zur grafischen ausgabe sagt der neue standard gar nichts (so wie der alte).



  • so, eine info: hab vor kurzem einige updates mithilfe des neuen working-drafts hier (und im anderen artikel) vorgenommen. C++0x ist nun feature complete und es dürfte wohl viele leute freuen, dass alle features, die hier vorgestellt werden, auch wahrscheinlich in dieser form, teil von C++0x werden. (ob C++0x nun C++09 wird oder C++0A steht zwar noch in den sternen, aber ich bin zuversichtlich 🙂 )



  • Da gab's doch in diesem Komitee einen Kerl, der gegen alles gevoted hat was Concepts angeht, mit der Begründung dass er befürchtet, dass es zu unausgereift ist und hier ein falscher Grundstein gelegt wird. Weiß man genaueres darüber, was seine Befürchtungen sind?



  • das war david vandevoorde (der sich mit templates ja wirklich gut auskennt), was genaueres weiß ich auch nicht, aber das könnte man ja einmal in comp.lang.c++.moderated besprechen.



  • Ich habe eine Frage zu den variadic templates. Wenn ich als template-Argumente eine Liste von ints habe, möchte ich ja auch auf die einzelnen Einträge zugreifen können. Geht also sowas wie:

    template <int ...x> struct foo
    { 
      static const int bar[sizeof...(x)] = { x... };
      const int operator[](const int i)
      {
        return bar[i];
      }
    };
    
    int main()
    { 
      foo<0, 0, 0> f;
      return f[1];
    }
    

    Oder gibt es eine andere Möglichkeit? 😕



  • Purrrfect schrieb:

    Ich habe eine Frage zu den variadic templates. Wenn ich als template-Argumente eine Liste von ints habe, möchte ich ja auch auf die einzelnen Einträge zugreifen können. Geht also sowas wie:

    template <int ...x> struct foo
    { 
      static const int bar[sizeof...(x)] = { x... };
      const int operator[](const int i)
      {
        return bar[i];
      }
    };
    
    int main()
    { 
      foo<0, 0, 0> f;
      return f[1];
    }
    

    Oder gibt es eine andere Möglichkeit? 😕

    Früher war afaik der Syntax [].[index] im Gespräch - afaik ist der aber nicht durchgekommen.
    Deine Möglichkeit wär' wohl möglich - schöner wär aber was mit constexpr...



  • queer_boy schrieb:

    das war david vandevoorde (der sich mit templates ja wirklich gut auskennt), was genaueres weiß ich auch nicht, aber das könnte man ja einmal in comp.lang.c++.moderated besprechen.

    Please forgive me for responding in English: I don't write German.

    Here is my position on C++0x concepts. It's an interesting feature, but it is currently unimplemented. There is a partial implementation (ConceptGCC) of an earlier specification, but what was voted in the working paper is significantly different. That brings about a fair number of risks, in my opinion:
    - Potentially breaking significant existing code (because of library changes) in ways we are not aware of.
    - Potentially being programmer-unfriendly (i.e., I worry that I might more often than not find writing a constrained template to be an unpleasant affair).
    - Potentially have an excessive number of semantic holes (i.e., having to significantly revise/extend the specification long after the language standard has been published).
    - Potentially being excessively expensive to implement.

    Note that I'm not saying that "C++0x concepts are a bad idea"; instead I say "There is -- in my opinion -- insufficient evidence that the current incarnation of C++0x concepts is a well-executed good idea".

    Part of the problem here is that we're dealing with a very large feature that is essentially added "all at once" to the language. (Compare that to the original templates, which were added to the language by bits and pieces, and then eventually standardized after we had industrial experience with most of it.)

    Hopefully, my worries will turn out to be unfounded.

    Daveed



  • Hallo, queer_boy! Meinen Respekt für die Arbeit, die du in den Artikel gesteckt hast.

    Hier sind ein paar Anregungen und Verbesserungsvorschläge:

    Zu Variadischen Templates: Man könnte noch erwähnen, dass der eingebaute "sizeof..."-operator eigentlich ein template a la count_args<>::value erspart. Das 3. Codebeispiel scheint einen copy/paste Fehler zu enthalten. Statt

    template <class T, class ...Args>
    T* make_new (Args&& ...args)
    {
       //expandiert automatisch richtig:
       return new T( *new Args(static_cast<Args&&>(args)) ...);
    }
    

    müsste es doch eigentlich heißen

    template <class T, class ...Args>
    T* make_new (Args&& ...args)
    {
       //expandiert automatisch richtig:
       return new T(static_cast<Args&&>(args)...);
    }
    

    oder nicht?

    Zu Rvalue-Referenzen: Das Beispiel "Optimierungen von std::string" wird nach den neuen Regeln nicht kompilieren und ist auch nicht wirklich im Sinne der Spracherweiterung. Das Zurückgeben von Referenzen birgt die Gefahr von "baumelnden Referenzen". Nach den neuen Regeln binden Rvalue-Referenzen auch keine Lvalues mehr. Aber das, was Du zurückgiebst sind Lvalue-Ausdrücke. In neueren Beispielen findet man soetwas:

    string operator+(string && a, string const& b)
    {
      a += b;
      return move(a);
    }
    

    Das move() ist hier notwendig, weil 'a' ein Referenz-Parameter ist, der wie ein Lvalue-Ausdruck behandelt wird. (Das move() ist aber bei lokalen Variablen überflüssig und sollte vermieden werden, weil es die NRV-Optimierung des Compilers umgehen könnte).

    Neue Funktions-Syntax: Ich glaube nicht, dass Deine typedefs und die Deklaration des Arrays a korrekt sind. Der Deklarator sitzt da an der falschen Stelle:

    typedef (auto (int) -> int) F; // Falsch
    typedef auto F(int) -> int;    // Richtig
    

    Lambdas: Soweit ich weiß, fehlt da bei dem einen oder anderen Lambda-Ausdruck die Return-Anweisung und/oder ein Semikolon. Einige Klammern sind auch falsch. Beispiel:

    int i = [](int x, int y) (x + y) (42,23);       // Falsch
    int i = [](int x, int y) {return x+y;} (42,23); // Richtig
    

    Das war's erstmal von mir.

    Gruß,
    Sebastian



  • Ich probiere gerade die Beta1 vom VS 2010 aus, mal eine Frage: Kann man die Lambda-Funktionen eigentlich "ordentlich" übergeben? Mit VS klappt sowas:

    template<typename T>
    void whatever( T calc )
    {
    	std::cout << calc( 10 ) << std::endl;
    }
    
    int main()
    {
        whatever( [](int x)->int {return x*2;} );
    }
    

    Würde gerne den Typ angeben (also zumindest Parameter-Anzahl), konnte dazu im Artikel aber nichts finden.



  • Kleine frage noch.
    Ich glaube das das auhc noch dazu gehört^^

    In C hat man ja die endungen C & H benutzt für Quellcode daten und header
    in C++ wurden folgende mit eingeeführt: CPP & HPP.
    Jedoch habe ich auch CXX und HXX gefunden, haben diese ihren ursprung aus dem C++0x Standard oder wo kommen diese her?

    Mfg Wikinger75!



  • Badestrand schrieb:

    Ich probiere gerade die Beta1 vom VS 2010 aus, mal eine Frage: Kann man die Lambda-Funktionen eigentlich "ordentlich" übergeben? Mit VS klappt sowas:

    template<typename T>
    void whatever( T calc )
    {
    	std::cout << calc( 10 ) << std::endl;
    }
    
    int main()
    {
        whatever( [](int x)->int {return x*2;} );
    }
    

    Würde gerne den Typ angeben (also zumindest Parameter-Anzahl), konnte dazu im Artikel aber nichts finden.

    Ein Lambda-Ausdruck generiert ein Objekt eines einzigartigen aber anonymen Typs. Die Template-Parameter-Herleiting des Compilers ist das einzige, was Dich direkt ein Lambdaobjekt halten lässt. Das schlißt auch "auto" mit ein:

    int main()
    {
        auto f = [](int x)->int {return x*2;};
        whatever( f );
    }
    

    Du kannst aber so ein Funktionsobjekt mit Hilfe der "Type Erasure"-Technik in einem anderen Funktionsobjekt kapseln. Dazu ist das Bibliotheks-Feature "std::function" gedacht:

    #include <functional>
    
    void whatever( std::function<int(int)> calc )
    {
    	std::cout << calc( 10 ) << std::endl;
    }
    
    int main()
    {
        whatever( [](int x)->int {return x*2;} );
    }
    

    Hier wird das Lambda-Objekt implizit zu einem std::function<int(int)> objekt konvertiert. Hinter dem Vorhang läuft das mit Laufzeit-Polymorphie (abstrakte Basis-Klasse mit virtuellen Funktionen). Man kann aber davon ausgehen, dass eine qualitativ gute Implementierung von std::function sehr effizient bei "kleinen" Funktionsobjekten funktioniert. In diesem Fall hat Dein Lambda-Objekt gar keinen "Zustand". Es sollte also von der "small-function-optimization" profitieren. Bei großen Funktionsobjekten muss man hier auf den Freispeicher ausweichen.

    Bis vor kurzem gab es noch eine andere Möglichkeit, Lambda-Objekte, die entweder gar nichts einfangen oder alle Variablen im umliegenden Geltungsbereich per Referenz fangen: reference_closure<>. Dieser Ansatz war aber nicht viel besser als std::function. Er wurde deswegen wieder aus dem Entwurf genommen.

    Gruß,
    Sebastian


Anmelden zum Antworten