Iteratoren für (C-Style) Array generieren



  • Hi,

    gibt es eine Möglichkeit für einen "einfachen" Array Iteratoren zu generieren? Ich möchte die Daten aber nicht kopieren. Es geht darum für bestimmte Bereiche eines Arrays einen begin() und end() Iterator zu generieren.

    int* array = new int [10];
    auto beg = std::begin(array, 5);
    auto end = std::end(array, 8);
    


  • 1. Du willst keine dynamischen C-Arrays.
    2. Es gibt nicht "End-Iteratoren" und "Start-Iteratoren", es sind alles einfach nur Iteratoren. Also std::begin(array)+5 für das 5. Element und std::begin(array)+9 für das Ende des Bereichs 5-8.
    3. Du willst wirklich kein new verwenden.



  • endl-iter schrieb:

    1. Du willst keine dynamischen C-Arrays.

    Möchte ich auch nicht, aber die verwendete Bibliothek.

    endl-iter schrieb:

    2. Es gibt nicht "End-Iteratoren" und "Start-Iteratoren", es sind alles einfach nur Iteratoren. Also std::begin(array)+5 für das 5. Element und std::begin(array)+9 für das Ende des Bereichs 5-8.

    Den Ansatz hatte ich auch, aber std::begin mag die einfachen Arrays nicht.

    /usr/include/c++/4.9.2/bits/range_access.h:48:5: error: request for member 'begin' in '__cont', which is of non-class type 'int*'
    

    endl-iter schrieb:

    3. Du willst wirklich kein new verwenden.

    Siehe 1 😉



  • Tschuldigung, Denkfehler meierseits. begin ist gar nicht nötig, Pointer sind Iteratoren.

    int* array = new int [10];
    auto beg = array + 5;
    auto end = array + 8;
    


  • c++neuu schrieb:

    endl-iter schrieb:

    1. Du willst keine dynamischen C-Arrays.

    Möchte ich auch nicht, aber die verwendete Bibliothek.

    Gib mehr Infos: welche Bibliothek? Für was? Was macht die mit dem Speicher? Geht auch ein vector oder deleted die denn selber?

    endl-iter schrieb:

    2. Es gibt nicht "End-Iteratoren" und "Start-Iteratoren", es sind alles einfach nur Iteratoren. Also std::begin(array)+5 für das 5. Element und std::begin(array)+9 für das Ende des Bereichs 5-8.

    Den Ansatz hatte ich auch, aber std::begin mag die einfachen Arrays nicht.

    /usr/include/c++/4.9.2/bits/range_access.h:48:5: error: request for member 'begin' in '__cont', which is of non-class type 'int*'
    

    Das ist ja auch kein Array, das ist ein Zeiger auf einen Speicherbereich, der groß genug ist für 10 Elemente. std::begin/end gibts dafür nicht. Ein Iterator ist nichts anderes als dieser Zeiger, begin ist der Zeiger selber, end Zeiger + size, das i-te Element Zeiger + i.



  • Vielen Dank, manchmal macht man sich selber das Leben schwer ... 👍

    endl-iter schrieb:

    Tschuldigung, Denkfehler meierseits. begin ist gar nicht nötig, Pointer sind Iteratoren.

    int* array = new int [10];
    auto beg = array + 5;
    auto end = array + 8;
    


  • c++neuu schrieb:

    Vielen Dank, manchmal macht man sich selber das Leben schwer ... 👍

    Zum Beispiel mit unnötigem new.



  • Nathan schrieb:

    c++neuu schrieb:

    Vielen Dank, manchmal macht man sich selber das Leben schwer ... 👍

    Zum Beispiel mit unnötigem new.

    Jetzt muss ich doch mein bisschen Restehre verteidigen 😉 Es ging darum, dass ich eine alte C-Bibliothek verwenden muss, welche sehr viele Daten (ca. 1 Gig) läd und man diese dann über Zeiger verwenden kann. Ist leider relativ viel mit Offset rumgerechne. Ich hatte jetzt einfach einen Wrapper dafür geschrieben, sodass man einfach begin() und end() für die einzelnen Bereiche verwenden kann, ohne dass die Daten einmal in mehrere std::vector Instanzen kopiert werden müssen.


  • Mod

    Ich verstehe nicht, wo hier ein new einen Unterschied zu einem vector machen sollte. Meinst du die einmalige Initialisierung am Anfang? Und wenn schon new, dann mit einem Smartpointer.

    Bloß weil eine API einen Pointer will, heißt das in keinster Weise, dass man selber Pointer zur Verwaltung der Daten verwenden muss oder gar sollte. Man muss die Daten bloß auf eine Art und Weise verwalten, die einem erlaubt, später einen Pointer darauf herzustellen. Also so wie (unter anderem) vector.



  • void oldCStyleFunction(int * buf, int maxlen);
    
    int main()
    {
    	std::vector<int> v(255, 0);
    	oldCStyleFunction(v.data(), v.size());
    
    	std::string s = "abcd";
    	strlen(s.c_str());
    }
    

    Solche Geschichten gehen ja immer noch. Eventuell mit etwas (const weg-) gecaste, aber so kannst du immer noch alte C Bibliotheken nutzen.



  • Skym0sh0 schrieb:

    void oldCStyleFunction(int * buf, int maxlen);
    
    int main()
    {
    	std::vector<int> v(255, 0);
    	oldCStyleFunction(v.data(), v.size());
    	
    	std::string s = "abcd";
    	strlen(s.c_str());
    }
    

    Solche Geschichten gehen ja immer noch. Eventuell mit etwas (const weg-) gecaste, aber so kannst du immer noch alte C Bibliotheken nutzen.

    Ich meinte es genau umgekehrt. Wir haben z.B. gegeben:

    struct Foo {
        float* data;
        int* startIndices;
        int* ranges;
        int** someStuff;
    }
    
    A* load(...);
    

    Die Daten wollte ich nicht in einen Vector umkopieren. Darum habe ich einen Wrapper gemacht.

    class Bar {
        float* beginRange1();
        float* endRange1();
    
        float* beginRange2();
        float* endRange2();
    private:
        Foo* data;
    }
    


  • Dann zeig mal ein paar konkrete Zeilen, wie du die Bibliothek nutzt bzw. nutzen musst.



  • endl-iter schrieb:

    Tschuldigung, Denkfehler meierseits. begin ist gar nicht nötig, Pointer sind Iteratoren.

    int* array = new int [10];
    auto beg = array + 5;
    auto end = array + 8;
    

    Heist das ich kannwann immer eine Funktion der Standardbiliothek einen Iterator zurückgibt, diesen wie einen Pointer benutzen und umgedreht ? Oder wenn einen Funktion einen Pointer will, ihr einfach nen Iterator geben ?



  • unsure schrieb:

    endl-iter schrieb:

    Tschuldigung, Denkfehler meierseits. begin ist gar nicht nötig, Pointer sind Iteratoren.

    int* array = new int [10];
    auto beg = array + 5;
    auto end = array + 8;
    

    Heist das ich kannwann immer eine Funktion der Standardbiliothek einen Iterator zurückgibt, diesen wie einen Pointer benutzen und umgedreht ? Oder wenn einen Funktion einen Pointer will, ihr einfach nen Iterator geben ?

    Nein. Es gibt das Konzept eines Iterators und manche Typen erfüllen dieses Konzept.
    Ein Zeiger ist ein Iterator.
    Ein vector<int>::iterator ist ein Iterator.

    Aber ein Iterator ist kein Zeiger.



  • Hier stand Mist. Hab mich von dem Fettgedruckten verwirren lassen.



  • endl-iter schrieb:

    Aber ein Iterator ist nicht notwendigerweise ein Zeiger.

    FTFY.


Log in to reply