Problem mit Vector >_<



  • vector<char> app( const char *str1 , const char *str2 , long length )
    {
      vector <char>var(length);
      //...
      return var;
    }
    

    und

    std::vector<char> v;
    v = app(str1,str2,26);
    

    oder

    std::vector<char> v(app(str1,str2,26));
    


  • Am besten, du gibst App einen Vektor per Referenz mit, in den es dann schreibt!

    void app( std::vector< char >& theVec, const char* a, const char* b, unsigned int count )
    {
       / ....
    }
    
    int main()
    {
        std::vector< char > myVec;
    
        app( myVec, str1, str2, 26 );
    }
    


  • Decimad schrieb:

    Am besten, du gibst App einen Vektor per Referenz mit, in den es dann schreibt!

    void app( std::vector< char >& theVec, const char* a, const char* b, unsigned int count )
    {
       / ....
    }
    
    int main()
    {
        std::vector< char > myVec;
    
        app( myVec, str1, str2, 26 );
    }
    

    Und was ist daran besser? Der vector soll ein Rückgabewert sein, dann mach ihn auch zu einem. Gehts dir um Geschwindigkeit? Want Speed? Pass by Value.



  • Decimad schrieb:

    Am besten, du gibst App einen Vektor per Referenz mit, in den es dann schreibt!

    Dann schreib aber auch noch, was der Vorteil davon ist 😉

    In meinem Fall muss der Vector bei der Rückgabe noch kopiert werden.

    Vorteil meiner Variante ist, dass man sofort sieht, was denn eigentlich
    zurückgeliefert wird. Ab c++0x ist Dank eines zusätzlichen Features
    keine mehr Kopie mehr nötig.
    Zudem wird dein Kompiler die Kopie in deinem Fall sicherlich wegoptimeren.



  • XSpille schrieb:

    Ab c++0x ist Dank eines zusätzlichen Features
    keine mehr Kopie mehr nötig.

    Inwiefern ändert sich mit C++ 0x die RVO? Ich kenne keinen Compiler, der die Kopie wirklich machen würde.



  • Schaut bitte mal auf die Zeit!
    Mein Posting bezog sich nicht auf das von XSpille.



  • vec schrieb:

    ...

    Du würdest uns allen helfen, wenn du deinen Code besser formatierst (Sinnvoll einrückst, Abstände auf ein sinnvolles Minimum reduzierst, und vor allem den Code durch verständliche Bezeichner lesbarer machst).

    Eine weitere sinnvolle Regel: Eine Funktion sollte nach Möglichkeit nur eine Aufgabe erfüllen.

    Die Rückgabe eines Vectors kann man genauso wie bei jeder anderen Variablen machen: "return objekt;"

    std::vector foo()
    {
        std::vector v;
        // ...
        return v;
    }
    


  • Michael E. schrieb:

    Inwiefern ändert sich mit C++ 0x die RVO?

    Es liegt nicht daran, dass sich an der RVO etwas ändert, sondern an der
    Einführung von rvalue-Referenzen.
    Ich bin da leider noch kein Fachmann, aber da wird dann ein anderer Konstruktor
    aufgerufen:

    Foo(Foo&& foo){ // EDIT2: Ui... Ich glaub das const war falsch (Kann es leider atm nicht testen)
    }
    

    Dieser geht davon aus, dass das Foo-Objekt danach nicht mehr verwendet wird
    und beim vector, der den (sicherlich) implementiert, wird der interne Zeiger
    (so vermute ich) auf 0 gesetzt, so dass der Inhalt nicht kopiert werden muss.
    Ein minimaler Overhead bleibt vermutlich trotzdem.

    Falls meine Aussage nicht ganz korrekt ist, lasse ich mich gerne korrigieren.

    Michael E. schrieb:

    Ich kenne keinen Compiler, der die Kopie wirklich machen würde.

    Sobald deine Funktion virtual ist, wird es vermutlich schwer.
    Und wenn verschiedene Vectoren in der Funktion erstellt werden.

    EDIT: Ich glaub ein analoger Zuweisungsoperator existiert auch für vector.



  • Decimad schrieb:

    Schaut bitte mal auf die Zeit!
    Mein Posting bezog sich nicht auf das von XSpille.

    Ist nen Argument 🙄



  • Ja, sobald R-Value-Referenzen unterstützt werden, werde ich sie dankend nutzen und mich freuen. Hat eigentlich viel zu lange gedauert, das 😃 Bis dahin hab ich mich dran gewöhnt, das halt per übergebener Referenz dem Optimierer vorwegzunehmen (so er es denn für mich tun würde, ich muss es nicht kontrollieren! 🙂 ) und es bedeutet ja nun auch nicht wirklich mehr Schreibaufwand.



  • So lässt sich die Variable ja jetzt zurück geben.

    Aber wie kann ich mit C++ den jetzt die Daten ausgeben ohne z.b. eine for Schleife zu benutzen ?

    ( Falls wer ein Tutorial kennt wo so etwas behandelt wird plz posten ^^
    Den hier steht nix davon: http://www.dreamincode.net/forums/topic/33631-c-vector-tutorial/ )

    😡 So langsam nerven diese Vektoren aber ich will wissen wie der Müll funktioniert xD

    @asc
    Ja meine Code einrückung das hab ich schon 1000 mal gehört das mein Code angeblich nicht so leserlich ist jedoch weiss ich nicht was daran schlecht eingerückt sein soll meiner Meinung nach ist das Geschmackssache.
    Du kannst ja mal zeigen wie du den einrücken würdest.

    #include <iostream>
    #include <windows>
    #include <vector>
    #include <fstream>
    using namespace std;
    
    vector <char> app (  char *str1 ,  char *str2 , long length) ;
    
    int main()
    {
    
    char *str1 = "Das ist eine ";
    char *str2 = "Test Funktion";
    
    vector<char>ret;
    
        ret = app (  str1,  str2  ,  26  );
    
    cout<<ret[0];
    // cout<<ret; //[C++ Fehler] Unit1.cpp(26): E2094 'operator<<' ist im Typ 
     // 'ostream' für Argumente des Typs 'vector<char,allocator<char> >' nicht  
     // implementiert
    
    // printf("%s",ret);   // gibt den string komplett aus
    
    system("PAUSE");
    }
    //---------------------------------------------------------------------------
    
    vector <char> app (   char *str1 ,  char *str2 , long length )
    {
    vector <char>var(length);
    int j;
    
            for (unsigned long i=0 ; i< strlen(str1)  ; i++)
            {
                    var [i] = str1[i];
            }
    
            for (unsigned long i= strlen(str1) , j=0 ; i<strlen(str2) , j<strlen(str2) ; i++,j++ )
            {
                    var [i] = str2[j];
            }
    
            #define tes
            #ifdef test
            for ( long i=0 ; i < length ; i ++ )
            {
                    cout<<var[i];
            }
            #endif
    
    var[length] = '\0';
    
    return var;
    }
    


  • Auf irgendeine Form von Schleife musst du sowieso zurückgreifen, ob sichtbar oder versteckt. Wenn du es nur nicht sehen willst, musst du einen Funktor schreiben, der das Argument im operator() auf cout ausgibt und dann bspw. std::for_each verwenden.



  • Einen Functor kenne ich noch nicht da muss ich mich dann nochmal mit beschäftigen.

    Genau so wie mit dem Vector >_<

    Ich hab das Problem jetzt erst mal so gelöst.

    #include <iostream>
    #include <windows>
    #include <vector>
    #include <fstream>
    using namespace std;
    
    vector <char> app (  char *str1 ,  char *str2 , long length);
    void print_vector( vector<char>ret );
    
    int main()
    {
    
    char *str1 = "Das ist eine ";
    char *str2 = "Test Funktion";
    vector<char>ret;
    
        ret = app (  str1,  str2  ,  26  );
        print_vector( ret );
    
    cout<<endl;
    
    system("PAUSE");
    }
    //---------------------------------------------------------------------------
    
    vector <char> app (   char *str1 ,  char *str2 , long length )
    {
    vector <char>var(length);
    int j;
    
            for (unsigned long i=0 ; i< strlen(str1)  ; i++)
            {
                    var [i] = str1[i];
            }
    
            for (unsigned long i= strlen(str1) , j=0 ; i<strlen(str2) , j<strlen(str2) ; i++,j++ )
            {
                    var [i] = str2[j];
            }
    
            #define tes
            #ifdef test
            for ( long i=0 ; i < length ; i ++ )
            {
                    cout<<var[i];
            }
            #endif
    
    var[length] = '\0';
    
    return var;
    }
    
    void print_vector( vector<char>ret )
    {
    
            for ( unsigned  i=0 ; i < ret.size() ; i++ )
            {
                 cout<< ret [i];
            }
    
    }
    


  • Da du ja auf Form auch nicht so viel Wert legst...^^...

    template< typename T >
    class ostreamer {
    public:
        ostreamer( ostream& o ) : stream_( o ) {}
    
        void operator()( const T& arg ) {
            stream_ << elem;
        }
    private:
        std::ostream& stream_;
    };
    
    template<typename T>
    std::ostream& operator<<( std::ostream& stream, const std::vector<T>& vec )
    {
         std::for_each( vec.begin(), vec.end(), ostreamer<T>(stream) );
         return stream;
    }
    
    void somefunc() {
        std::vector< char > some;
    
        // ...
        std::cout << some;
    }
    

    Wahrscheinlich gibts noch irgendeinen Trick mit output-iteratoren um sich den Funktor zu sparen. Oder du verwendest gleich std::string's.



  • vec schrieb:

    Ja meine Code einrückung das hab ich schon 1000 mal gehört das mein Code angeblich nicht so leserlich ist jedoch weiss ich nicht was daran schlecht eingerückt sein soll meiner Meinung nach ist das Geschmackssache.

    Dein Code lässt sich ähnlich schlecht lesen, wie dieser Satz (der entweder in viele kleine Sätze, oder durch Kommata getrennt gehört).

    Grobe möglichst allgemein gehaltene Regeln für eine lesbare Formatierung:
    1. Rücke Code nach den Scopes (Geltungsbereichen) ein.
    - Negativbeispiel: z.B: Deine Variablendeklaration in der main(), im Vergleich zu den später folgenden Code...
    2. Übertreibe Codeabstände nicht (1 Leerzeile reicht in der Regel).
    - Negativbeispiele wirst du selbst finden...
    3. Sei konsequent bei den Einrückungen und Abständen.
    - Negativbeispiel: z.B: "var [i] = str1[i]"

    Ich rücke mal deinen letzten Code so ein, wie ich es machen würde, auch wenn es verschiedene Varianten gibt:

    #include <iostream>
    #include <windows>
    #include <vector>
    #include <fstream>
    
    using namespace std;
    
    vector<char> app(
        char *str1,
        char *str2,
        long length);
    void print_vector(
        vector<char> ret);
    
    int main()
    {
        char *str1 = "Das ist eine ";
        char *str2 = "Test Funktion";
        vector<char>ret;
    
        ret = app(str1, str2, 26);
        print_vector(ret);
        cout << endl;
    
        system("PAUSE");
    }
    
    //---------------------------------------------------------------------------
    
    vector<char> app(
        char *str1,
        char *str2,
        long length)
    {
        vector <char>var(length);
        int j;
    
        for(unsigned long i=0; i<strlen(str1); i++)
        {
            var [i] = str1[i];
        }
    
        for(unsigned long i= strlen(str1), j=0; i<strlen(str2), j<strlen(str2); i++,j++)
        {
            var [i] = str2[j];
        }
    
    // Bedingte Makros lege ich in der Regel auf die erste Ebene, um diese sofort
    // zu sehen...
    #define tes
    #ifdef test
        for ( long i=0 ; i < length ; i ++ )
        {
            cout<<var[i];
        }
    #endif
    
        var[length] = '\0';
        return var;
    }
    
    void print_vector(
        vector<char> ret)
    {
        for(unsigned  i=0; i<ret.size(); i++)
        {
            cout<< ret [i];
        }
    }
    


  • vec schrieb:

    Aber wie kann ich mit C++ den jetzt die Daten ausgeben ohne z.b. eine for Schleife zu benutzen ?

    Immer wenn du Daten in einer Liste hällst musst du dich auch darum kümmern diese zu durchlaufen.

    Aber ja, es gibt Kurzformen. Nur werden sie für dich nicht unbedingt verständlich sein:

    #include <algorithm> // u.a. std::copy
    #include <iostream>
    #include <iterator>  // u.a. std::ostream_iterator
    #include <vector>
    
    int main()
    {
       std::vector<int> v;
       v.push_back(123);
       v.push_back(456);
       v.push_back(789);
    
       // Ausgabestream-Iterator mit Trennzeichen (hier z.B. "-").
       std::ostream_iterator<int> output(std::cout, "-");
       // Vectorinhalt nach cout "kopieren"
       std::copy(v.begin(), v.end(), output);
    
       // Kurzform:
       std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "-"));
    }
    


  • Da war er der output-iterator! 😃 Ich huldige ihm!



  • Danke für die Antworten.

    Da hab ich ja noch einiges zu tun. (:


Anmelden zum Antworten