In Datei schreiben in einer Unterfunktion



  • Obligatorischer Hinweis, dass man einen vector an eine reine Ausgabefunktion nicht by-value übergeben sollte, sondern als const-ref:

    void ausgabe(vector<vector<int>> const& matrix, ofstream& output) 
    { 
        output << "bla"; 
    }
    

    Weiterer Hinweis, dass man keine Referenz auf ofstream als Parameter nehmen sollte, wenn man auch mit einem ostream auskommt (was in deinem Programm vermutlich der Fall sein wird), also:

    void ausgabe(vector<vector<int>> const& matrix, ostream& output) 
    { 
        output << "bla"; 
    }
    


  • hustbaer schrieb:

    Obligatorischer Hinweis, dass man einen vector an eine reine Ausgabefunktion nicht by-value übergeben sollte, sondern als const-ref:

    kommt drauf an, was das profiling sagt. Wenn ein Programm 0.1% der Laufzeit in der Ausgabefunktion by-value verbringt, kann man sich const & wohl sparen.



  • Dankeschön,
    Ich habe jetzt die Ausgabefunktion in der main und übergebe ostream&. Die Berechnungsfunktionen geben die jeweils notwendige Vektoren-Matrix zurück, die dann von der Ausgabefunktion verwendet wird.
    Das mit der Länge des vector<vector<int>> habe ich im Griff. Sobald die notwendige Größe eingelesen wurde, setze ich alle Vektoren auf eine feste Länge.



  • großbuchstaben schrieb:

    hustbaer schrieb:

    Obligatorischer Hinweis, dass man einen vector an eine reine Ausgabefunktion nicht by-value übergeben sollte, sondern als const-ref:

    kommt drauf an, was das profiling sagt. Wenn ein Programm 0.1% der Laufzeit in der Ausgabefunktion by-value verbringt, kann man sich const & wohl sparen.

    const& hinten dranzuschreiben ist kein Aufwand und hat - wenn man eh nur Lesen will - keine Nachteile.
    Wieso es sich dann "sparen"? Was soll das bringen? 6 Buchstaben weniger tippen müssen?

    Bei sowas spart man Zeit indem man sich angewöhnt es immer und überall "richtig" zu machen. Geht viel schneller als sich 100x am Tag zu überlegen was der Profiler wohl dazu sagen könnte. Und dann noch die Stellen nachträglich suchen zu dürfen wo man falsch geraten hat.



  • großbuchstaben schrieb:

    hustbaer schrieb:

    Obligatorischer Hinweis, dass man einen vector an eine reine Ausgabefunktion nicht by-value übergeben sollte, sondern als const-ref:

    kommt drauf an, was das profiling sagt. Wenn ein Programm 0.1% der Laufzeit in der Ausgabefunktion by-value verbringt, kann man sich const & wohl sparen.

    C++ Coding Standards: Premature pessimization.
    Es schadet auf keinen Fall und ist nahezu kein Mehraufwand. Exakt dasselbe mit i++ und ++i.


  • Mod

    TerenceNr1 schrieb:

    Das mit der Länge des vector<vector<int>> habe ich im Griff. Sobald die notwendige Größe eingelesen wurde, setze ich alle Vektoren auf eine feste Länge.

    Du bezahlst aber trotzdem die Kosten, alleine für die Möglichkeit, dass der vector<vector> auch flexibler sein kann.



  • hustbaer schrieb:

    großbuchstaben schrieb:

    hustbaer schrieb:

    Obligatorischer Hinweis, dass man einen vector an eine reine Ausgabefunktion nicht by-value übergeben sollte, sondern als const-ref:

    kommt drauf an, was das profiling sagt. Wenn ein Programm 0.1% der Laufzeit in der Ausgabefunktion by-value verbringt, kann man sich const & wohl sparen.

    const& hinten dranzuschreiben ist kein Aufwand und hat - wenn man eh nur Lesen will - keine Nachteile.
    Wieso es sich dann "sparen"? Was soll das bringen? 6 Buchstaben weniger tippen müssen?

    nein, das const sollte aus systematischen Gründen natürlich bleiben. Es geht um das "&".

    Ich kleistere meinen handgepflegten Code nicht aus Jux und Tollerei mit Sonderzeichen zu. Ich ersetze pass-by-value für gewöhnlich erst dann, wenn es einen Grund gibt, und den liefert mir das profiling (falls es nicht ohnehin offensichtlich sein sollte, wie etwa bei 3-mal aufgerufenen Funktionen mit 20 Bytes Argument)



  • großbuchstaben schrieb:

    nein, das const sollte aus systematischen Gründen natürlich bleiben.

    Dem stehe ich im Moment zwiegespalten gegenüber. Momentan mach ich's nicht, weil's mir irgendwie komisch vorkommt. Allerdings conste ich so-gut-wie alle lokalen Variablen die sich nimmer ändern werden. Und Parameter sind ja auch nix grundlegend anderes als lokale Variablen. Also wieso nicht die auch consten?
    Hmmm...
    Egal. Darum ging's mir nicht.

    großbuchstaben schrieb:

    Es geht um das "&".

    Genau 🙂

    großbuchstaben schrieb:

    Ich kleistere meinen handgepflegten Code nicht aus Jux und Tollerei mit Sonderzeichen zu.

    Ist ja nicht aus Jux und Tollerei.

    Dinge wie new/delete oder CAS sind in der Regel nicht ganz billig (verglichen mit dem Auf-Den-Stack-Pushen eines Zeigers), und können in der Regel vom Compiler auch nicht "as if" wegoptimiert werden. Weil er in der Regel nicht beweisen kann dass sie nicht beobachtbar sind.

    großbuchstaben schrieb:

    Ich ersetze pass-by-value für gewöhnlich erst dann, wenn es einen Grund gibt, und den liefert mir das profiling (falls es nicht ohnehin offensichtlich sein sollte, wie etwa bei 3-mal aufgerufenen Funktionen mit 20 Bytes Argument)

    OK.
    Ich bin mir nicht sicher wie gut man Slowdowns die durch Verzicht auf pass-by-const-ref entstehen mit nem Profiler erkennen kann. Ich hab' da meine Zweifel.
    Ich müsste es wohl mal ausprobieren.

    Nur: ich sehe einfach keinen Grund der dagegen spricht.
    Das mit den Sonderzeichen kann ja wohl (hoffentlich) nur ein Scherz gewesen sein. Ist für mich auf jeden Fall kein akzeptabler Grund.



  • hustbaer3e schrieb:

    Und Parameter sind ja auch nix grundlegend anderes als lokale Variablen. Also wieso nicht die auch consten?

    Im Interface bringts nichts, sondern ist unnötige Information für den Aufrufer. Natürlich könnte man Deklaration und Definition verschieden schreiben, aber das führt auch wieder zu Fragen. Top-Level- const für Parameter oder Rückgabetypen finde ich echt mühsam. Ist bei vielen Codes ein Hinweis, dass der Autor diverse C++-Konzepte nicht verstanden hat, besonders wenn die Antwort auf die Frage "warum" dies bestätigt... War zumindest meine Erfahrung.

    Davon abgesehen drückt man mit dem Parametertyp auch Semantik, besonders im Bezug auf Besitz, aus. const T& bedeutet in meinem Code "Funktion liest lediglich Werte aus", während T mittlerweile nicht selten auf ein Move hinweist. Ist kein 100% verlässlicher Indikator, aber hat bei mir dazu geführt, dass ich const Klassentyp& sofort als nicht speziell wahrnehme, während ich bei Pass-by-Value jeweils kurz überlege, warum es jetzt so angegeben wurde.

    Schlussendlich ist das recht subjektiv, aber wenn man sich an gewisse semantische Regeln hält, kann bereits wenig Code sehr viel aussagen. Hab ich auch gemerkt, als ich in letzter Zeit wieder vermehrt in Java entwickeln musste, wo wir anhand der Signatur rein gar nichts erkennen.



  • Geh Nexus, dass das top-level const bei Parametern nicht zur Signatur gehört, und daher in bei der Deklaration nix verloren hat (weil sinn- und wirkungslos), das weiss ich doch.
    (top-level const beim Returnwert gehört dagegen natürlich zur Signatur - ist aber mMn. aus anderen Gründen plem)

    Mir geht's schon um die Definition.
    Weil dort dadurch dokumentiert wird "keine sorge, ich änder das nicht, mussdu nicht die ganze Funktion lesen sondern darfst du sicher sein".
    Weswegen ich es bei lokalen Variablen überall drankleistere.

    void foo(int /*wieso hier kein const*/ param)
    {
        int const /* aber hier schon */ bar = compute_bar(param);
    }
    

    Und da hab ich einfach keinen *guten* Grund dafür. Mein schlechter Grund ist: weil ich es komisch finde. Unpassend. Ungewohnt.
    Nur vor etlichen Jahren fand ich das const bei "bar" auch komisch, unpassend, ungewohnt. Und heute schreib' ich es ohne nachzudenken hin. Genau so wie explicit bei Konstruktoren und hoffentlich bald sealed bei C++/CLI ref bzw. C# Klassen - wenn ich es endlich schaffe mir das anzugewöhnen.



  • mir ist es wichtig, schnell im Code navigieren zu können und dazu muß relevante Information möglichst deutlich hervorgehoben sein, und irrelevante Information möglichst unterdrückt. Ziel ist selbsterklärender Code.

    "const" ist für mich eine wichtige Information, um bspw in der Deklaration auf einen Blick zu erkennen, ob ein Parameter ein Rückgabewert ist oder nicht. Oder ob eine Methode das Objekt ändert.

    "&" ohne "const" ist für mich keine sonderlich relevante Information; es sagt mir vor allem, daß das entsprechende Argument so groß werden könnte, daß pass-by-value ineffizient werden könnte, was mit einem Profiler zu überprüfen wäre.

    "const&" wiederum ist eine relevante Information für mich, sagt es mir doch, daß es sich beim zugehörigen Parameter 1. nicht um einen Rückgabewert handelt und 2. daß pass-by-value hier einen Unterschied machen könnte / die Funktion bereits optimiert ist.



  • oops, jetzt habe ich's genau verkehrt herum geschrieben 👎

    Gemeint ist:

    "const&" und "const" ist für mich erst bei Effizienzfragen von Relevanz, "&" alleine hingegen von Anfang an relevant (Rückgabewert).


Anmelden zum Antworten