Vector zurückgeben



  • Wieder eine Frage. Diesmal gehts über Rückgabewerte.
    Ich hab nun eine Datei in eine vector/string-Variable eingelesen und möchte diese zurückgeben. Wie mach ich das am besten? Ich möchte dass dann der Wert aus dem Speicher wieder rausgenommen wird.



  • vector/string-Variable

    Was ist das denn ?

    Ich möchte dass dann der Wert aus dem Speicher wieder rausgenommen wird.

    Welcher Wert ?
    Am Besten: Code zeigen und Fragen nochmal formulieren.



  • Lumio schrieb:

    Wieder eine Frage. Diesmal gehts über Rückgabewerte.
    Ich hab nun eine Datei in eine vector/string-Variable eingelesen und möchte diese zurückgeben. Wie mach ich das am besten? Ich möchte dass dann der Wert aus dem Speicher wieder rausgenommen wird.

    Am besten call by reference und nicht per return. Also etwa so:

    #include<string>
    #include<vector>
    #include<iostream>
    
    using namespace std;
    
    bool einlesen(string& puffer) {
        puffer = "hallo Puffer";
    }
    
    void einlesenInVector(vector<string>& puffer) {
       puffer.push_back("hallo welt");
    }
    
    int main() {
        string irgendeinString;
        vector<string> irgendeinVector;
    
        einlesenInVector(irgendeinVector);
    
        einlesen(irgendeinString);
    
        return 0;
    }
    


  • Gibt es keine Möglichkeit mit return? Andernfalls ist diese Art sicherlich besser 🙂 Danke.



  • Lumio schrieb:

    Gibt es keine Möglichkeit mit return?

    Doch, aber willst du wirklich den riesigen Container unnötig kopieren?



  • Nein, will ich nicht, aber es gibt sicherlich andere Situationen, wo es durchaus nicht schlecht sein kann, dies zu wissen, oder? 🙂



  • Nexus schrieb:

    Lumio schrieb:

    Gibt es keine Möglichkeit mit return?

    Doch, aber willst du wirklich den riesigen Container unnötig kopieren?

    dürfte ich da nicht auf RVO hoffen?



  • Lumio schrieb:

    Nein, will ich nicht, aber es gibt sicherlich andere Situationen, wo es durchaus nicht schlecht sein kann, dies zu wissen, oder? 🙂

    Ah ja, das sicher. 😉

    std::vector<std::string> BaueEinenSatz()
    {
        std::vector<std::string> Vec;
        Vec.push_back("Hallo");
        Vec.push_back("wie");
        Vec.push_back("gehts?");
        return Vec;
    }
    

    volkard schrieb:

    dürfte ich da nicht auf RVO hoffen?

    Daran habe ich vorhin auch gedacht, aber hat RVO nicht manchmal Probleme, wenn benannte Variablen im Spiel sind? Ich würde das Risiko nicht um jeden Preis eingehen wollen...



  • Chris++ schrieb:

    Am besten call by reference und nicht per return.

    Einen Wert als Referenz übergeben zu lassen und ihn in der Funtkion zu ändern ohne ihn zurückzugeben sollte man imho möglichst vermeiden. Solche Aufrufe sind ungewohnt, unintuitiv und deshalb schwerer lesbar, nicht so leicht verständlich und deshalb nicht so einfach wartbar. Ich würde daher eher einen Modifizierer schreiben, ähnlich den streamoperatoren:

    vector<string>& einlesenInVector(vector<string>& puffer, string const& arg) 
    { puffer.push_back(arg); return puffer; }
    

    Nexus schrieb:

    volkard schrieb:

    dürfte ich da nicht auf RVO hoffen?

    Daran habe ich vorhin auch gedacht, aber hat RVO nicht manchmal Probleme, wenn benannte Variablen im Spiel sind?

    Im Gegenteil - nennt sich dann NRVO 😉



  • pumuckl schrieb:

    Im Gegenteil - nennt sich dann NRVO 😉

    Und darauf kann man sich quasi immer verlassen? Macht es also gar keinen Sinn mehr, zum Beispiel Klassenmember als Const-Referenz zurückzugeben, ausser sie sind nicht kopierbar?



  • Nexus schrieb:

    pumuckl schrieb:

    Im Gegenteil - nennt sich dann NRVO 😉

    Und darauf kann man sich quasi immer verlassen? Macht es also gar keinen Sinn mehr, zum Beispiel Klassenmember als Const-Referenz zurückzugeben, ausser sie sind nicht kopierbar?

    Wow... und das heisst?
    Und was ist ein Modifizierer und das oben genannte Beispiel ist für mich nicht verständlich



  • Optimierung von unnötigen Kopien bei Rückgabewerten:

    http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx

    Das bedeutet soviel, dass der Compiler so schlau sein kann und gewisse Fälle, wo ein Rückgabewert (vom Code her) kopiert werden sollte, aber schlussendlich (bei gewissen Bedingungen) eben doch nicht, was dann halt eine Optimierung darstellt.



  • Also wenn ich

    vector<string> readfile (char foo[], string& var)
    

    habe, dann kommt folgender Fehler: error: expected constructor, destructor, or type conversion before '<' token
    Das selbe, wenn ich std:: vor vector und string verwende.



  • #include <vector>
    #include <string>
    

    Aber vorher hat es doch auch funktioniert? Zumindest waren die Header bereits in gepostetem Code...



  • Ähm xD Danke 😃



  • Nexus schrieb:

    pumuckl schrieb:

    Im Gegenteil - nennt sich dann NRVO 😉

    Und darauf kann man sich quasi immer verlassen?

    Nein, kann man nicht. Ist schließlich nicht im Standard festgelegt.
    google/wikipedia können da sicher mehr sagen. Boost hat für die Frage auch ein entsprechendes Compilerflag:

    #include <boost/config.hpp>
    
    #ifdef BOOST_HAS_NRVO
      cout << "Mit NRVO :)" << endl;
    #else 
      cout << "Ohne NRVO :(" << endl;
    #endif
    

    MSVC 2008 hats z.B. im Release-Modus drin, im Debug-Modus nicht.



  • Vielen Dank für die Erläuterung, das kam mir zuerst so rüber. Dann war mein anfänglicher Einwand also doch nicht ganz unangebracht... 😉

    Besonders das mit dem Boost-Flag ist interessant. Auch wenn es umständlich ist, für seinen Code jeweils zwei Versionen anzubieten. Aber so oft wird das wahrscheinlich nicht vorkommen...


Anmelden zum Antworten