Was würdet ihr an C++ verbessern?



  • Zu Delegates: die Bindung funktioniert nur an den aktuellen this-Zeiger, die Parameter müssen übereinstimmen. Mit bind kann ich alles aufrufen, was man callen kann, ich kann binden, was ich will, das Funktionsziel muss nicht die korrekten Parameter haben (die kann ich um-binden) usw.
    Diese Vorteile in C++ übertragen sich dann natürlich auf Signale/Events. Brauchst du in jedem Event den Sender- oder den EventArg-Parameter? Warum musst du ihn dann immer hinschreiben? Du wolltest schonmal einen zusätzlichen Parameter an den Event-Delegaten übertragen? Tja, Pech. Da musst du dir wohl ne neue Klasse schreiben, die diesen Parameter aufnehmen kann und die Verarbeitung übernimmt.
    bind ermöglicht sowas ohne jegliche Mehrkosten.

    Davon abgesehen muss ich sagen, von LINQ bin ich ein bisschen begeistert. Mir ist bisher auch nicht eingefallen, wie man das genau so umfangreich in C++ nachbauen könnte.



  • Irgendwer schrieb:

    Auch werde ich wohl nie verstehen, warum sie keine freien Funktionen erlauben. Immer "public static" vor eine Funktion schreiben zu müssen, nervt...

    http://blogs.msdn.com/b/ericlippert/archive/2009/06/22/why-doesn-t-c-implement-top-level-methods.aspx

    Bashar schrieb:

    SideWinder schrieb:

    ipsec schrieb:

    verstehe ich bis heute nicht, warum keine Defaultwerte für Parameter zulässig sind.

    AFAIK ist das mit C# 4.0 gekommen, oder?

    Ja. Immer das gleiche, man fängt mit einer kleinen, "sauberen" Sprache an, weist auf die Komplexität von C++ hin, aber dann baut man nach und nach alles rein, was man eigentlich mal absichtlich weggelassen hatte.

    Die optionalen Parameter wurden eigentlich nur im Zuge von dynamic eingeführt. Das Hauptproblem war ja, dass C++ und VB6 optionale Parameter bieten und die beiden meistbenutzten Sprachen für COM sind. Dem entsprechend war es oft ziemlich ätzend, aus .NET COM anzusprechen, weil man auch optionale Parameter mitangeben musste. Das führte zu deutlich mehr Schreibaufwand. In dem Bereich ist man jetzt aus dem Schneider.
    Für normalen .NET Code wird die Verwendung von optionalen-Parametern aber dennoch nicht empfohlen. Und zwar deshalb, weil der Defaultwert fest in den die Funktion aufrufenden Code kompiliert wird (verhält sich analog zum const-Schlüsselwort, darum benutzt man besser readonly).
    Ich denke, dass gerade dieses Feature unglücklich umgesetzt ist und wirklich nur für Interop/COM benutzt werden sollte.

    Oh, ach ja... C# ftw 111elf! :p



  • this->that schrieb:

    + Weg mit den Scheiss Headern

    👍
    Einheitliches Format für libs, damit alle Compiler miteinander können.
    Keine automatische Konvertierung int <-> bool...



  • Michael E. schrieb:

    Regex-Literale. Reguläre Ausdrücke sind sowieso schon schwer zu lesen, da will ich nicht noch jedes zweite Symbol escapen müssen.

    Ich habe etwas mit Raw-Literalen ohne Escape-Sequenzen in Erinnerung... Ist das nicht mehr aktuell?

    Bashar schrieb:

    Wieso versagt? Das ist ein Feature, dass man absichtlich nicht drin hat.

    Naja, mit final hat man es halbwegs drin, aber eben nicht konsequent. Ausserdem gibts Immutable-Klassen, es besteht also zumindest eine schwache Tendenz zur Const-Correctness. Nicht zuletzt hat man sich mit const als nutzloses reserviertes Schlüsselwort ein Hintertürchen offen gelassen 😉



  • Bei const correctness weiß ich auch nicht, ob mir das schon jemals was gebracht hat und nen bug verhindert hat.



  • Und ich hab' nie verstanden wie man eine moderne Sprache noch ohne const-correctness ausliefern kann. Das ist also tatsächlich nicht universal als notwendig und super angesehen?

    MfG SideWinder



  • Nexus schrieb:

    Michael E. schrieb:

    Regex-Literale. Reguläre Ausdrücke sind sowieso schon schwer zu lesen, da will ich nicht noch jedes zweite Symbol escapen müssen.

    Ich habe etwas mit Raw-Literalen ohne Escape-Sequenzen in Erinnerung... Ist das nicht mehr aktuell?

    Ehrlich gesagt wusste ich nicht, dass dieses Feature Thema für C++0x ist oder war. Es ist mir lediglich als erstes eingefallen 😉



  • Ich finde, die Entwicklung von C++98 nach C++0x überwiegend positiv. Mir fallen jetzt auch auf Anhieb nicht so viele Dinge ein, die mich da stören:

    • die Sonderregel bei Template-Argument-Deduktion bei P=T&&, wobei P der Funktionsparametertyp und T der Typparameter ist, für die Implementierung von "perfect forwarding". Das wird eine Sache, über die noch viele stolpern werden, schätze ich.
    • Lambdas: Das "Capturing" ist zu restriktiv (kein Move-Capture, Beschränkung auf Entitäten aus dem lokalen Scope) und es gibt keine Möglichkeit aus anonymer_lamda_object_typ::operator() ein Template zu machen (aka "polymorphe lambdas").
    • Late return-type: Ich muss bei der neuen Funktionsdeklarationssyntax immer noch einen return-Typ angeben, obwohl ich bei Lambdas dazu nicht mehr gezwungen werde. Das finde ich inkonsequent. Beispiel:
    auto sum1(int a, int b) -> int {return a+b;}  // OK
    auto sum2(int a, int b) {return a+b;}         // nicht erlaubt
    
    int main() {
      auto sum3 = [](int a, int b){return a+b;};  // OK
    }
    

    In diesem Beispiel ist das nicht wild. Es kann aber bei komplizierteren Funktionstemplates nerven, dass man den RückgabeTyp noch zusätzlich angeben muss. Gut, man könnte sich mit decltype ein Makro baseln, um das zu emulieren, aber das ist dann auch nicht so schön.

    Sonst wäre es vielleicht noch nett, eine bessere Unterstützung für Pimpl bereitzustellen. ZB wäre es nett, wenn man so etwas machen könnte

    incomplete_type *ptr = ...;
    ptr->some_function(27,3.1415);
    

    also, Klassen partiell zu definieren (öffentliche Schnittstelle im Header verraten, aber mehr auch nicht, also keine Implementierungsdetails). Der Typ würde dann noch unvollständig sein, man könnte aber trotzdem Elementfunktionen (zumindest die, die im Header deklariert werden) aufrufen. Damit spart man sich das Bauen einer Pimpl-Wrapper Klasse und das Replizieren der Schnittstelle.

    Ein Modulsystem wär auch nicht schlecht. Hatte mir auch das Proposal mal dazu angesehen, aber so richtig durchblickt hatte ich das auch nicht.

    Mir wär auch ein einfaches Sprachfeature recht, mit welchem ich diese enable_if-Tricks loswerde. Die Anwendung des enable_if-Tricks führt zu schwer lesbarem Code und der Trick ist auch nicht überall einsetzbar, wo man es bräuchte. Ein aufgeblasenes concept-System muss nicht unbedingt sein. Aber wenn man eine einfache requires-Klausel mit boolschen Ausdrücken einführt, dann verbaut man sich vielleicht damit die Möglichkeit für ein besseres concepts-System.



  • ich wuerde gerne eine automatische oder simple art accessor functions zu erstellen gern im standard sehen, so wie es automatisch ctor/dtor gibt.

    also

    class foo
    {
    int bar;
    };
    

    sollte automatisch

    int bar();
    int bar()const;
    template<class T>
    void bar(const T& b){bar=b;}
    }
    

    [edit:tags fixen]
    als public bekommen.

    oder wenigstens "simple art", so dass man angibt welche art, z.b.

    class foo
    {
    int bar:public:Bar;
    };
    

    ps. das ist nur brainstorming, kein final draft meines vorschlages 😉

    zudem waere eine ueberarbeitung von den std::... nett, sowas wie .c_str()... ist mir ein grauss.

    zudem wuerde ich gerne die compiler richtlinien ueber aliasing usw. ueberarbeitet sehen, sodass compiler besser optimieren koennen. ansonsten sind simple optimierungen wie loop unrollen oft verhindert, weil irgendwelche aliasing rules anschlagen von denen die meisten garnicht wahrnehmen dass es passiert.

    (nicht dass ich hier jetzt einen flamewar anstossen will, aber ich verstehe ehrlich nicht was hier manche gegen header dateien haben, wenn ich mir so manch java sourcefile anschaue, ist das echt nicht so schoen zu ueberblicken wie ein simpler c++ header, wenn man etwas einfach nur benutzen will, was die meiste zeit ueber sein duerfte, wenn man fremden source nimmt).



  • @rapso: Kurz gesagt: Du willst also auch Properties? 🤡

    Zum Thema Header noch: Java ist so modular aufgebaut, dass jede noch so billige IDE dir ein wunderbares Outline angibt und du fast überall auch mit irgendeiner Tastenkombination in die Ehre kommst zu einer Methode einfach via Namenseingabe zu springen. Ich glaube soetwas geht noch nicht einmal in der aktuellsten VC++-Version.

    MfG SideWinder



  • Also ich schaue in keine Header-Datei! MSVC zeigt mir das alles "grafisch" an, und ich benutze auch IntelliSense/VisualAssist, so das ich on the fly die Klassen, Funktionen und Parameter einsehen kann. Wer bitte öffnet da noch die Header? Und dann gibt es da noch die API-Reference (siehe Boost, MSDN u.a.), die mir hoffentlich jede gute Library mitliefert. Wenn nicht, ist die Library eh verdammt, in der Tonne zu landen.

    Die Headers aus solch einem Grund zu befürworten, lässt mich echt zweifeln. 🙄



  • SideWinder schrieb:

    Tastenkombination in die Ehre kommst zu einer Methode einfach via Namenseingabe zu springen. Ich glaube soetwas geht noch nicht einmal in der aktuellsten VC++-Version.

    Ob das MSVC2010 kann, weiß ich nicht. Aber die meisten haben VisualAssist X, und da geht das natürlich:

    Shift+Alt+S geht der Symbol/Object-Browser auf
    Alt+M listet alle Methoden/Funktionen vom aktuellen File
    Alt+G Springe in die Implementierung
    Shift+Alt+F Find References
    Alt+O Öffnet korrespondierendes File (h/cpp)

    und eine Datei-Outline in der Sidebar gibt es natürlich auch (schon seit VC6).

    Also, sooo zurück geblieben sind die C++-Tools auch wieder nicht. 🙄 Und VAX macht da seine Sache schon sehr gut! Ich kann das als täglicher Java-Eclipse User gut vergleichen.



  • Ich als Student bin zwar in der glücklichen Lage sowohl Eclipse als auch Visual Studio 2010 Professional zu erhalten. Allerdings müsste ich für Visual Assist X extra zahlen. "Dann programmier' ich doch mal lieber in Java".

    MfG SideWinder



  • ipsec schrieb:

    In C#:

    ThreadData d = new ThreadData();
    Thread t = new Thread(new ParameterizedThreadStart(foo)); // Die Syntax ist so umständlich, dass man bei Delegates per Spracherweiterung den Typ weglassen könnte. Bei allen anderen Typen kann man es aber nicht.
    t.Start(d);  // Übergabe typunsafe als Objekt. Außerdem könnte ich genauso gut die parameterlose Start-Methode aufrufen, das wird höchstens zur Laufzeit geprüft
    

    So ist es typsafe:

    ThreadData d = new ThreadData();
    Thread thread = new Thread(() => foo(d));
    thread.Start();
    

    Oder kurz:

    new Thread(() => foo(new ThreadData())).Start();
    

    😃



  • kurz ist für mich eher so was:

    foo := [ ... ] forkAt: 10.
    


  • Ieh, eckige Klammern für Nicht-Feldbereiche.

    Was habt ihr alle gegen Header? Wo soll ich denn sonst meine Klasse definieren?



  • Wenn ich um eine API/Lib bedienen zu koennen in den Header schauen muss, dann is sie eh Schrott.
    Eine gute API liefert eine ordentliche Doku. Ich hatte z.B. in DirectX oder .NET noch NIE das Beduerfnis in irgend einen Header zu schauen. Man klickt einfach auf den relevanten Typ, drueckt F1 und bekommt eine uebersichtliche Hilfe ohne den ganzen irrelevanten Spam wie #includes, #defines, private Member usw.

    Eisflamme schrieb:

    Was habt ihr alle gegen Header? Wo soll ich denn sonst meine Klasse definieren?

    Seit wann definiert man Klassen in Header?
    Offenbar hast du dir noch nie moderne Sprachen wie Java oder C# angeschaut...



  • Eisflamme schrieb:

    Ieh, eckige Klammern für Nicht-Feldbereiche.

    Was habt ihr alle gegen Header? Wo soll ich denn sonst meine Klasse definieren?

    Direkt in einer Datei? Diese Trennung von Deklaration (und dank Templates auch oft Definition) und Definition ist ja nicht universal. Schau' mal über den Tellerrand. Ich glaube da sind C/C++ einige der wenigen Sprachen die ein solches Konzept verfolgen.

    MfG SideWinder



  • Also wenn schon Trennung von Definition und Implementierung der Funktionen. Im Header steht ja die Klassendefinition.[/klugscheiß]

    Hm... Ich fand das gar nicht so schlimm. Und wenn man nur ÜE hat und keine Header, muss sich der Compiler automatisch die Abhängigkeiten zurechtsuchen oder wollt ihr dann eine andere Bekanntmache haben? Oder inkludiert man dann die ÜE bzw. ist nicht mehr jede Quellcodedatei eine ÜE?

    Edit: Oh, ich schreibe auch nicht ÜEs. Interessant.



  • Und wenn man nur ÜE hat und keine Header, muss sich der Compiler automatisch die Abhängigkeiten zurechtsuchen

    Genau. Wo ist das Problem?
    So eine Aufgabe kann doch auch gerne der Compiler übernehmen.


Anmelden zum Antworten