Eure Wünsche an Sprachfeatures für den nächsten Standard (nach C++11)



  • Tachyon schrieb:

    krümelkacker schrieb:

    314159265358979 schrieb:

    Burkhi schrieb:

    - Funktionszeiger auf Methoden eines Objekts

    Wenn du Methodenzeiger meinst, die gibts doch schon. Oder meinst du was anderes?

    Er meint Funktionszeiger auf "gebundende" Funktionen -- die also schon mit einem bestimmten Objekt verknüpft sind -- quasi den this-Parameter mit beinhalten.

    Bekommt man das nicht quasi mit std::bind und std::function ?

    Nichts, was man an C-APIs übergeben könnte.



  • Burkhi schrieb:

    - Funktionszeiger auf Methoden eines Objekts

    Das wird es nicht geben. C++11 zeigt doch eindeutig, dass variable(?) Funktionen durch Funktionsobjekte ausgedrückt werden, und damit ist das was du brauchst jetzt schon möglich.

    Ethon schrieb:

    Nichts, was man an C-APIs übergeben könnte.

    Geht das etwa mit den gebundenen Methodenzeigern aus dem C++-Builder? Würde mich a) wundern und b) stark interessieren, wie die das realisieren.



  • 314159265358979 schrieb:

    3.) "Forward typedef"
    Deklariert einen Typen, allerdings können auch typedefs deklariert werden, z.B.:

    typedef std::string;
    typedef std::istream;
    

    Dazu hab ich hier mal was geschrieben.

    audacia schrieb:

    Reflection.

    Wird eher nicht kommen, siehe z.B. hier. Aber eine kontrollierte Form der Reflection (z.B. für einzelne Klassenhierarchien) wäre ab und zu schon praktisch.

    asc schrieb:

    Ebenso fände ich eine Abkehr von der C-Kompatibilität nicht schlecht, und damit verbunden ein Aufräumen im C++ Standard. Sinnvoll wäre dann natürlich ein Schlüsselwort das Übergänge definiert um mit C kommunizieren zu können (Vergleichbar mit z.B. C# und "unsafe" das Bereichsweise Zeiger zulässt).

    Fände ich auch gut. Nicht das ganze C (Zeiger oder Makros sind z.B. sehr sinnvoll), aber Features wie Variadic Arguments, register , von mir aus auch C-Casts halte ich nicht für nötig. Aber auch C++-Features wie Exceptionspezifikationen, alternative Schlüsselwörter. Oder Teile der Standardbibliothek, wie z.B. std::bind1st() , std::ptr_fun() , std::auto_ptr . Teilweise sind sie ja schon deprecated.

    Ethon schrieb:

    Tachyon schrieb:

    Bekommt man das nicht quasi mit std::bind und std::function ?

    Nichts, was man an C-APIs übergeben könnte.

    Ja gut, aber nur aus diesem Grund würde ich keine Sprachmittel einführen. Viele C-Callback-APIs haben eh einen void* userData -Parameter...



  • asc schrieb:

    Was ich mir wünschen würde, und was vermutlich niemals kommt wäre eine ABI-Änderung die zumindest auf dem jeweiligen Betriebsystem Bibliotheken (wie lib/dll unter Windows) direkt ermöglich, die auch vom Compiler unabhängig sind und Klassen etc. über die Schnittstellen hinweg zulassen.

    Nennt sich COM, und gibt es sogar auf Windows, Mac OS X und VMS implementiert!

    Muß nur auf weiteren Plattformen implementiert werden und natürlich müssen COM-Objekte bereit gestellt werden. Und schon kann man zumindest auf einer Plattform Compiler-unabhängig OO-APIs nutzen.

    MS wird es mit Windows 8 noch weiter treiben.



  • Aber COM in C++ ist einfach nur fürchterlich. Insofern finde ich die Forderung nach einem einheitlichen ABI auch sinnvoll, wenngleich mindestens so weltfremd wie die Forderung nach Reflection 😉

    Gebundene Funktionszeiger in C++Builder (Stichwort __closure ) können auch nicht an C-APIs übergeben werden. In C++-Code ist bind() eine Alternative, allerdings ist ein __closure deutlich effizienter und kommt ohne zusätzliche Allokationen aus. Der eigentliche Grund für die Einführung des Sprachmittels war aber die Binärkompatibilität zu Delphi. Und mit der Einführung von anonymen Funktionen in Delphi einerseits und Lambda-Funktionen in C++ andererseits werden diese gebundenen Funktionszeiger vermutlich an Bedeutung verlieren.



  • Artchi schrieb:

    asc schrieb:

    Was ich mir wünschen würde, und was vermutlich niemals kommt wäre eine ABI-Änderung die zumindest auf dem jeweiligen Betriebsystem Bibliotheken (wie lib/dll unter Windows) direkt ermöglich, die auch vom Compiler unabhängig sind und Klassen etc. über die Schnittstellen hinweg zulassen.

    Nennt sich COM, und gibt es sogar auf Windows, Mac OS X und VMS implementiert!

    Nur ist COM
    a) unterschiedlich weit implementiert (OS-bezogen)
    b) unschön zu programmieren, lieber wäre mir eine direkte Sprachintegration
    c) nicht wirklich konsistent zum restlichen C++ (Betrifft auch dei Sprachintegration)

    Artchi schrieb:

    MS wird es mit Windows 8 noch weiter treiben.

    Ja, aber dies ist kein Standard der einfach so mal auf alle OS portiert wird.



  • Ihr habt mich auf die Idee gebracht, Pseudo-Reflection zu implementieren.
    Habe es mal ähnlich wie in Java gemacht: http://ideone.com/maCfY
    Offenbar gibts bei Ideone kein boost::any.



  • Tachyon schrieb:

    krümelkacker schrieb:

    314159265358979 schrieb:

    Burkhi schrieb:

    - Funktionszeiger auf Methoden eines Objekts

    Wenn du Methodenzeiger meinst, die gibts doch schon. Oder meinst du was anderes?

    Er meint Funktionszeiger auf "gebundende" Funktionen -- die also schon mit einem bestimmten Objekt verknüpft sind -- quasi den this-Parameter mit beinhalten.

    Bekommt man das nicht quasi mit std::bind und std::function ?

    Ja. Allerdings hat ein "gebundener Funktionszeiger" einen Platzvorteil als auch einen Geschwindigkeitsvorteil -- selbst dann, wenn std::function per "small function object optimization" implementiert wird -- also bei kleinen Funktionsobjekten ohne den Freispeicher auskommt.

    Das Aufrufen einer Methode über Funktionszeiger und Objektzeiger erfordert ggf ein Pointer-Adjustment und ein vtable-Lookup. Speichert man beide Zeiger als "einen Kombizeiger", kann man diese Aktionen vorziehen, so dass später die Funktion "direkter" aufgerufen werden kann (ohne vtable-Lookup und ohne Pointer-Adjustment). Zeiger auf Elementfunktionen können dank virtueller Vererbung und solche Scherze schonmal etwas größer ausfallen (sizeof(void*)*3). Speichert man dazu den this-Zeiger, ist man schon bei sizeof(void*)*4, wohingegen ein einfacher "gebundener Funktionszeiger" nur sizeof(void*)*2 groß sein muss.

    Für eine Sprache wie C++, die eine "zero overhead"-Sprache sein will, sehe ich das als eine kleine Lücke. Aber die Lücke ist scheinbar nicht groß genug, dass man dafür einen neuen Funktionszeigertypen hat einführen wollen. So etwas wurde zumindest nicht für C++2011 vorgeschlagen. Richtig wichtig finde ich das jetzt auch nicht.



  • Das ist zwar etwas utopisch, aber ich wuerde mir mehr compile time reflection wuenschen. Vieles wurde ja schon umgesetzt, es fehlt aber noch die Moeglichkeit, eine Liste aller Member einer Klasse von ausserhalb abzufragen, ohne deren Namen, Anzahl oder Typ schon zu kennen.



  • GorbGorb schrieb:

    Das ist zwar etwas utopisch, aber ich wuerde mir mehr compile time reflection wuenschen. Vieles wurde ja schon umgesetzt, es fehlt aber noch die Moeglichkeit, eine Liste aller Member einer Klasse von ausserhalb abzufragen, ohne deren Namen, Anzahl oder Typ schon zu kennen.

    Kannst Du mal ein Beispiel nennen, wo das nützlich wäre?



  • krümelkacker schrieb:

    Tachyon schrieb:

    krümelkacker schrieb:

    314159265358979 schrieb:

    Burkhi schrieb:

    - Funktionszeiger auf Methoden eines Objekts

    Wenn du Methodenzeiger meinst, die gibts doch schon. Oder meinst du was anderes?

    Er meint Funktionszeiger auf "gebundende" Funktionen -- die also schon mit einem bestimmten Objekt verknüpft sind -- quasi den this-Parameter mit beinhalten.

    Bekommt man das nicht quasi mit std::bind und std::function ?

    Ja. Allerdings hat ein "gebundener Funktionszeiger" einen Platzvorteil als auch einen Geschwindigkeitsvorteil -- selbst dann, wenn std::function per "small function object optimization" implementiert wird -- also bei kleinen Funktionsobjekten ohne den Freispeicher auskommt.

    Das Aufrufen einer Methode über Funktionszeiger und Objektzeiger erfordert ggf ein Pointer-Adjustment und ein vtable-Lookup. Speichert man beide Zeiger als "einen Kombizeiger", kann man diese Aktionen vorziehen, so dass später die Funktion "direkter" aufgerufen werden kann (ohne vtable-Lookup und ohne Pointer-Adjustment). Zeiger auf Elementfunktionen können dank virtueller Vererbung und solche Scherze schonmal etwas größer ausfallen (sizeof(void*)*3). Speichert man dazu den this-Zeiger, ist man schon bei sizeof(void*)*4, wohingegen ein einfacher "gebundener Funktionszeiger" nur sizeof(void*)*2 groß sein muss.

    Für eine Sprache wie C++, die eine "zero overhead"-Sprache sein will, sehe ich das als eine kleine Lücke. Aber die Lücke ist scheinbar nicht groß genug, dass man dafür einen neuen Funktionszeigertypen hat einführen wollen. So etwas wurde zumindest nicht für C++2011 vorgeschlagen. Richtig wichtig finde ich das jetzt auch nicht.

    http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx?



  • @ipsec: Ja und? Der Artikel war mit bekannt. Das, was ich geschrieben habe, wird dadurch nicht widerlegt.



  • krümelkacker schrieb:

    @ipsec: Ja und? Der Artikel war mit bekannt. Das, was ich geschrieben habe, wird dadurch nicht widerlegt.

    Dort hast du doch aber Methodenzeiger mit gebundenen Objekt und Zero Overhead. Wenn man es genau so gut in eine Klasse packen kann, wiese sollte man es dann als Sprachfeature umsetzen? Das wiederum würde nicht der C++-Philosophie entsprechen.



  • ipsec schrieb:

    ...Zero Overhead...

    Das stimmt nicht.

    ipsec schrieb:

    ...wiese sollte man es dann als Sprachfeature umsetzen?...

    Ob man es sollte oder nicht, dazu nahm ich gar nicht Stellung.



  • Kannst Du mal ein Beispiel nennen, wo das nützlich wäre?

    Marshalling.



  • Vorbemerkung: Vielleicht bin ich ja nur zu blöd, das mit C++11 zu lösen, dann bin ich für jede Hilfe dankbar.

    Was mir fehlt, sind Container, in die ich Objekte aus einer Klassenhierarchie stecken kann, um dann später Methoden polymorph aufzurufen. Also etwa

    class A
    {
        virtual void foo();
    };
    
    class B : public A
    {
        virtual void foo();
    };
    
    vector<? extends A> myVec; // an java Generics angelehnt
    
    void create(void)
    {
        A a;
        B b;
    
        myVec.push_back(a);
        myVec.push_back(b);
    }
    
    void use(vector<? extends A> vec)
    {
        for(size_t i(0); i<vec.size; ++i)
        {
            myVec[i].foo();
        }
    }
    

    Heute löse ich das, in dem ich ein vector<A*> nehme. Das ist aber insofern nicht schön, weil die Objekte ja in irgendeiner Form im Speicher vorhanden sein müssen (statisch oder heap) und die benutzende Klasse nicht ohne Weiteres weiß, wo der Speicher für das Objekt her kommt.

    Also muss ich entweder jedem Objekt mitgeben, wie es alloziert wurde, oder ich verwende doubleDispatch. Letzters macht den Code aber (nicht nur) in den Augen derjenigen, die das nachher warten müssen, komplizierter.



  • Stichwort: Smartpointer.



  • @PI: Wie soll der helfen? Das sind Templates, die, wenn ich die in den Container stecke, doch jeweils einen eigenen Typ bilden, oder?

    class A
    {
        virtual void foo();
    };
    
    class B : public A
    {
        virtual void foo();
    };
    
    std::unique_ptr<A> a;
    std::unique_ptr<B> b; // ist ein anderer Typ als a
    

    Oder meinst Du

    class A
    {
        virtual void foo();
    };
    
    class B : public A
    {
        virtual void foo();
    };
    
    vector<std::unique_ptr<A>> myVec;
    
    myVec.push_back(new A);
    myVec.push_back(new B);
    

    Ich kann's hier leider gerade nicht ausprobieren.



  • class A
    {
        virtual void foo();
    };
    
    class B : public A
    {
        virtual void foo();
    };
    
    std::unique_ptr<A> a;
    std::unique_ptr<B> b; // ist AUCH ein A
    


  • Ah OK, da war Tachyon schneller (und bei mir ein klarer Fall von RTFM, weils in der VC10 Doku ja schon erklärt ist).

    Bestens, danke!


Anmelden zum Antworten