Vector als Rückgabewert einer Funktion?



  • Kurze Frage: Kann ich einen Vector von einer Funktion an eine andere Funktion uebergeben, beispielsweise um dort den Inhalt auszuwerten?

    Danke im voraus.

    Guenther



  • Natürlich... du musst aber den Typ festlegen, oder die Funktion muss auch ein template sein.

    // das geht:
    std::vector<int> getData();
    
    // das geht nicht:
    std::vector getData();
    

    rya.



  • Scorcher24 schrieb:

    Natürlich... du musst aber den Typ festlegen, oder die Funktion muss auch ein template sein.

    // das geht:
    std::vector<int> getData();
    
    // das geht nicht:
    std::vector getData();
    

    rya.

    In meiner Funktion habe ich ein

    vector<string>list_selected;
    

    stehen, das sollte dann also richtig sein.

    Und dann geht's weiter mit

    while (st.fetch())
        {
            list_selected.push_back(s);
        }
    
    int max = list_selected.size();
    
    cout << "Anzahl: " << max << endl;
    
    for (int index = 0; index < max; index++)
        {
            cout << list_selected.at(index) << endl;
        }
    

    Ich bin mir zwar nicht sicher, ob der Code so wirklich richtig ist, aber die Ausgabe funktioniert einwandfrei.

    Trotzdem habe ich immer noch nicht verstanden, wie ich den Vector nun an eine andere Funktion uebergeben kann um die weitere Auswertung dort vorzunehmen.

    Ein simples 'return list_selected' oder aber via Referenz duerfte nicht gehen, oder?



  • Doch genau so simpel ist es... allerdings solltest du nur eine Referenz übergeben, wenn das objekt nach der Funktion weiterlebt.

    Beispiel

    std::vector<int>& getData()
    {
       std::vector<int> data;
       return data; <-- schlecht, data wird nach der Funktion zerstört.
    }
    
    // Besser:
    std::vector<int> getData()
    {
       std::vector<int> data;
       return data; <-- gut, weil einfach eine Kopie übergeben wird...
    }
    

    Du kannst jeden Datentyp/Objekt einfach mit "return xy" zurückgeben :). Ist also keine Hexerei.

    edit: Hab dir ein kleines Beispielprogramm geschrieben, zu Veranschaulichung:

    #include <string>
    #include <vector>
    #include <iostream>
    
    std::vector<std::string> getData()
    {
        std::vector<std::string> data;
        data.push_back("foo");
        data.push_back("bar");
        return data;
    }
    
    int main()
    {
       std::vector<std::string> content;
       content = getData();
       std::cout << content.at(0) << std::endl;
       std::cout << content.at(1) << std::endl;
    }
    

    rya.



  • Scorcher24 schrieb:

    Doch genau so simpel ist es... allerdings solltest du nur eine Referenz übergeben, wenn das objekt nach der Funktion weiterlebt.

    Guter Hinweis, danke!

    Scorcher24 schrieb:

    Du kannst jeden Datentyp/Objekt einfach mit "return xy" zurückgeben :). Ist also keine Hexerei.
    rya.

    Und ich war mir so sicher, dass es so einfach bestimmt nicht gehen kann, dass ich's nicht mal probiert habe.

    Aber ok, so ist das halt imer mal wieder bei C++.

    Danke fuer Deine pronpte Hilfe ...

    Guenther



  • template<typename T>
    struct basic_string_array
    { typedef type std::vector< std::basic_string<T> >; }
    typedef string_array basic_string_array<char>::type;
    typedef wstring_array basic_string_array(wchar_t>::type;
    
    void get_default_value(string_array& dest)
    {
        dest.clear();
        for (std::size_t i = 0; i < 10; ++i) dest.push_back(i + 1);
    }
    
    int main()
    {
        string_array my_strings;
        get_default_value(my_strings);
    }
    

    Das ist performanter, als eine Kopie zu erzeugen 😛



  • (D)Evil schrieb:

    template<typename T>
    struct basic_string_array
    { typedef type std::vector< std::basic_string<T> >; }
    typedef string_array basic_string_array<char>::type;
    typedef wstring_array basic_string_array(wchar_t>::type;
    
    void get_default_value(string_array& dest)
    {
        dest.clear();
        for (std::size_t i = 0; i < 10; ++i) dest.push_back(i + 1);
    }
    
    int main()
    {
        string_array my_strings;
        get_default_value(my_strings);
    }
    

    Das ist performanter, als eine Kopie zu erzeugen 😛

    Whow, das sieht gut aus, uebersteigt aber derzeit noch meinen Horizont ... 😋

    Ich bin daher zunaechst mal Scorcher24 gefolgt und das klappt auch praechtig.

    Dennoch werde ich mich wohl in den naechsten Tagen auch mal mit Templates & Co beschaeftigen muessen ....

    Gruss

    Guenther



  • gboelter schrieb:

    (D)Evil schrieb:

    template<typename T>
    struct basic_string_array
    { typedef type std::vector< std::basic_string<T> >; }
    typedef string_array basic_string_array<char>::type;
    typedef wstring_array basic_string_array(wchar_t>::type;
    
    void get_default_value(string_array& dest)
    {
        dest.clear();
        for (std::size_t i = 0; i < 10; ++i) dest.push_back(i + 1);
    }
    
    int main()
    {
        string_array my_strings;
        get_default_value(my_strings);
    }
    

    Das ist performanter, als eine Kopie zu erzeugen 😛

    Whow, das sieht gut aus,

    nicht wirklich



  • Moin (D)Evil,

    (D)Evil schrieb:

    void get_default_value(string_array& dest)
    {
        dest.clear();
        for (std::size_t i = 0; i < 10; ++i) dest.push_back(i + 1);
    }
    
    int main()
    {
        string_array my_strings;
        get_default_value(my_strings);
    }
    

    Das ist performanter, als eine Kopie zu erzeugen 😛

    Was gefällt Dir an return value optimization nicht? Quasi jeder Compiler macht sowas ähnliches wie das von Dir geschriebene sowieso automatisch, wenn man einen Typ by-value zurückgibt.

    /EDIT: Meist wird das named return value optimization genannt. Finde ich aber doof, klappt ja auch bei Temporaries, also Werten ohne Namen.



  • Ich muss jetzt doch noch mal nachhaken, und bitte nicht gleich schlagen denn in diese Bereiche bin ich in meiner kurzen C++ Zeit noch nicht weiter vorgedrungen.

    Wozu brauche ich den Teil mit 'template, struct' etc?

    (D)Evil schrieb:

    template<typename T>
    struct basic_string_array
    { typedef type std::vector< std::basic_string<T> >; }
    typedef string_array basic_string_array<char>::type;
    typedef wstring_array basic_string_array(wchar_t>::type;
    

    Ich habe es bei mir jetzt so geloest:

    #include <string>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int browse(vector<string> &list_selected)
    {
        int id;
        int x=1;
        int y=3;
    
        for (int index = 0; index < max; index++)
        {
            str = list_selected.at(index);
            .
            // some other code ....
            .
        }
    
        // some other code ....
    
        return id;
    }
    
    int main()
    {
        int id;
    
        vector<string>list_selected;
    
        id = browse(list_selected);
        list_selected.clear();
    
        return 0;
    }
    

    und es funktioniert einwandfrei.

    Ist das Zufall oder mache ich da einen Denkfehler?

    Guenther



  • Nö, schaut doch gut aus...
    rya.


Anmelden zum Antworten