Moderner C++ Code soll auf spezifische Typen verzichten?



  • Ich habe bei stackoverflow eine Aussage gefunden, bei der ich nicht so recht weis was ich davon halten soll. So heißt es:

    Modern C++ code should be decoupled from specific functions / types

    Was sagen die Profis hier dazu? Sollte man wirklich auch feste Typen als Funktionsparameter verzichten und stattdessen auf Konstrukte wie boost::any oder boost::variant verwenden?

    Oder gennereller, was macht modernen C++ Code aus?



  • axels. schrieb:

    Ich habe bei stackoverflow eine Aussage gefunden, bei der ich nicht so recht weis was ich davon halten soll. So heißt es:

    Modern C++ code should be decoupled from specific functions / types

    Was sagen die Profis hier dazu? Sollte man wirklich auch feste Typen als Funktionsparameter verzichten und stattdessen auf Konstrukte wie boost::any oder boost::variant verwenden?

    Nein, auf keinen Fall. Das ist damit nicht gemeint, und unabhängig davon was gemeint ist wäre es auch eine ganz schlechte Idee.

    axels. schrieb:

    Oder gennereller, was macht modernen C++ Code aus?

    Ich denke es geht dabei um Templates und auto .
    (EDIT: Also ich meine: ich denke in dem zitierten Text geht es um Templates und auto -- nicht dass das alles wäre was "modernes C++" ausmacht. /EDIT)



  • Kannst du mal den Stackoverflow Beitrag verlinken? Zu dieser Aussage braucht es etwas mehr Kontext.



  • icarus2 schrieb:

    Kannst du mal den Stackoverflow Beitrag verlinken? Zu dieser Aussage braucht es etwas mehr Kontext.

    https://stackoverflow.com/questions/582331/is-there-a-way-to-instantiate-objects-from-a-string-holding-their-class-name?answertab=votes#tab-top

    Letzter Absatz



  • In dem speziellen Fall ist wohl die Verwendung von boost::function statt eines Funktionszeigers gemeint.
    Das ist meistens schon OK. Hat aber Overhead und sollte daher auch nicht als Default für alle Anwendungsfälle gewählt werden ohne nochmal drüber nachzudenken. Manchmal reicht halt doch ein einfacher Funktionszeiger.


  • Mod

    C++ ist stets eine Sprache mit einer Affinität zur Abstraktion gewesen. Die Quintessenz moderner C++-Programmierung ist die Parametrisierung von Funktionen mit dem bloßen Konzept eines Typen.

    Das bezieht sich weniger auf boost::any oder variant als auf statische Polymorphie mittels Templates und placeholder Typen, und bald auch Concepts.

    template <typename T>
    decltype(auto) f(T const& t) {
        auto x = t.getX();
        //..
        return x.bar();
    }
    

    Edit: Der Kontext ist anders als ich erwartet hatte, aber im Grunde läuft es auch hier darauf hinaus, konkrete Typen zu abstrahieren. Allerdings muss berücksichtigt werden, dass function nur dann Sinn macht, wenn der Funktor auch State haben kann. Muss er das nämlich nicht, reicht in jedem Fall ein Funktionszeiger, weil sowieso keine Memberfunktion aufgerufen werden soll. Abstraktion muss auch in Maßen eingesetzt werden--wenn nicht, ergibt sich oft ein Szenario wie die, die C Fundamentalisten gerne anführen, um Templates schlechtzureden. Siehe Boost.Graph.



  • Du sollst dich generell von konkreten Typen lösen, stattdessen arbeitest du mit Konzepten bzw. dem Prinzip des duck typing.

    Iteratoren sind z.B. alles, was man dereferenzieren, vergleichen und inkrementieren kann. Das hat man auch schon vor C++11 so gehalten, aber dank auto und decltype kann man das nun konsequent durchziehen.

    Du erwartest von Funktionen als Rückgabewert kein short oder signed long long mehr, sondern generell ein Integer oder sogar nur eine Zahl. Das kann einer der genannten Typen sein oder auch ein GMP bignum. Solange man damit rechnen kann und man es in einen String konvertieren kann, sollte dein Code keine weiteren Annahmen treffen.

    So würde ich in Zukunft auch neue library interfaces konzipieren. In der Dokumentation sollten keine konkreten Typen, sondern nur Konzeptnamen angegeben werden - zumindest, wo das sinnvoll ist.

    Das geht immer so weiter. Kein std::vector<Foo>, sondern Ranges, kein std::string, sondern integer ranges, kein KeyValuePair, sondern irgendwas, was "key" und "value" als member hat, kein toller_zeiger<foo>, sondern dereferenzierbare Objekte.

    Dennoch muss man nicht alles generisch machen, manche Problemstellungen lassen sich nach wie vor sehr gut durch herkömmliche Klassenstrukturen und Vererbung modellieren. Da darf/sollte man dann gerne weiterhin mit konkreten Typen arbeiten.



  • axels. schrieb:

    Oder gennereller, was macht modernen C++ Code aus?

    die Nutzung der Möglichkeiten moderner C++ Versionen zur Herstellung guter Software: Wartbar, erweiterbar, effizient, transparent, korrekt.

    Das war eig schon immer so, oder?


Anmelden zum Antworten