Typkonvertierungsproblem



  • template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    


  • sqrt(-1) schrieb:

    int (*ptr)[3];
    ptr = (->Typkonv.<-)getVoidPointer();

    Damit hast Du ein Array von drei Zeigern auf int.

    Eine Typkonvertierung von einem Zeiger in ein Array ist nicht moeglich.

    Wenn Du drei Pointer hast, musst Du jedem getrennt Speicher zuweisen, oder, wenn Du drei Pointer allokieren willst, nimm einen Zeiger auf Zeiger auf int:

    int** ptrptr = new int* [ 3 ];
    for ( int i=0; i<3; ++i ) {
       ptrptr[i] = new int [ 1000 ];
    }
    

    Wie gehabt liefert Dir dann "ptrptr[0]" den ersten Zeiger, "ptrptr[1]", den zweiten Zeiger und "ptrptr[2]" den dritten Zeiger.



  • Das war da ein Fehler von mir.
    Ich brauche ja einen Zeiger vom Typ eines gesammtes (z.B.) int Arrays.
    Geht dies überhaupt oder muss ich da auf eine Struktur ausweichen?



  • Wenn ich dich richtig versteh, dann ist es immer noch sowas:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    


  • Ich will aber nur einen Zeiger übergeben der z.B. vom Typ int[4] ist.

    Also um das Gesammtproblem zu schildern:

    Ich habe fünf void-Zeiger.
    Jeder dieser zeigt auf ein erstes Element.
    Je nach Zeiger ist das Element vom Typ:
    float[3]
    float
    byte[4]
    float[2]
    short

    Nach dem ersten Element kommt nicht gleich das nächste im Speicher, sondern erst nach einer gewissen Anzahl von Bytes.
    Die Anzahl an Elementen ist für alle Zeiger gleich.
    Also:
    float[n][3]
    float[n]
    byte[n][4]
    float[n][2]
    short[n]

    Ich möchte nun alle Elemente dieser Arrays in eine Datei speichern.
    Da ich nicht für jeden Array Typ eine eigene Funktion schreiben sollte, möchte ich eine template Funktion benutzen.

    Tja, die Frage ist nun wie ich dies machen sollte.



  • PS.: Die Arrays sollen einzeln gespeichert werden, also nicht alle auf einmal.



  • template<class T, int i, int j>
    void foo(T bar[i][j])
    {
        ...
    }
    

    😕



  • Noch mal genauer:

    Im Speicher liegen 3xfloat hintereinander.
    Darauf habe ich einen void-Zeiger.
    Dies 3xfloat sind aber nur ein Element.
    Nach n-Bytes kommen wieder 3xfloat.
    Nach 2*n-Bytes kommen wieder 3xfloat.
    Diese Elemente gibt es x mal.

    Das Ganze gibt es nicht nur mit 3xfloat, sonder noch in 4 weiteren Formaten(wie gezeigt) und deren Elementeanzahl ist immer x.

    Eine Template Funktion soll fähig sein alle Elemente des jeweiligen Typs in einer Datei zu speichern.
    Die Frage ist nun wie ich die Typenunterscheidung hinbekomme.

    Danke für all die Mühe! 😉



  • Und um noch einmal zu sagen warum ich glaub das dies nicht hilft:

    Michael E. schrieb:

    Wenn ich dich richtig versteh, dann ist es immer noch sowas:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    

    Hier würde man ja ein Array des Types T erstellen.
    Ich habe aber nur den Zeiger auf das erste Element.
    Und die möglichen Typen auf die der Zeiger zeigt, sind:

    float[3]
    float
    byte[4]
    float[2]
    short



  • Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen. Wie groß ist bei dir n?



  • Michael E. schrieb:

    Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen.

    Ich will an die Template Funktion doch nur einen Zeiger übergeben.
    Der Typ worauf der Zeiger zeigt ist einer von denen:

    float[3]
    float
    byte[4]
    float[2]
    short

    Dein Template-Vorschlag würde bei der Übergabe eines Zeiger aber eine Array von Zeigern als Parameter annehmen, oder?

    Wie groß ist bei dir n?

    Irgend eine Zahl, z.B. 40.



  • Um das eigentliche Problem auf den Nenner zu bringen:

    Wie kann ich am einfachsten einen Zeiger erstellen, der auf ein Objekt z.B. vom Typ float[3] zeigt?

    Denn wenn ich folgendes mache...

    float blah[3];

    ... ist blah ja ein Zeiger auf ein Objekt des Types float, nicht aber float[3] - so wie ich es brauche.

    Wenn ich wie vorgeschlagen folgendes mache:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    

    ... ist der Parameter ja ein Array aus i Elementen des Types T.
    Das bringt mir nichts weil ich ja einen Zeiger übergeben will und gleichzeitig den Typ (also z.B. float[3]) für das Template übermitteln muss.



  • sqrt(-1) schrieb:

    Michael E. schrieb:

    Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen.

    Ich will an die Template Funktion doch nur einen Zeiger übergeben.
    Der Typ worauf der Zeiger zeigt ist einer von denen:

    float[3]
    float
    byte[4]
    float[2]
    short

    Dein Template-Vorschlag würde bei der Übergabe eines Zeiger aber eine Array von Zeigern als Parameter annehmen, oder?

    template<class T, int i>
    void foo(T bar[i])    // bekommt ein eindimensionales Array, also sozusagen T*
    {
        ...
    }
    
    template<class T, int i, int j>
    void foo(T bar[i][j])    // erhält ein zweidimensionales Array, also sozusagen T**
    {
        ...
    }
    

    Wie groß ist bei dir n?

    Irgend eine Zahl, z.B. 40.[/quote]
    Damit ist mir nicht geholfen. Ist das irgendeine ganz rein zufällige Zahl? Ich glaub eher nicht.



  • Also es funktioniert z.B. folgendes:

    struct _ElementTypA
    {
      float Element[3];
    }*ElementTypA;
    
    struct _ElementTypB
    {
      float Element;
    }*ElementTypB;
    
    ElementTypA = (_ElementTypA*)getVoidPointer();
    ElementTypB = (_ElementTypB*)getVoidPointer();
    
    schreibeArray(ElementTypA);
    schreibeArray(ElementTypB);
    
    template <class _ElementTyp> void schreibeArray(_ElementTyp* ElementTyp)
    {
       ElementType ArrayPuffer[100];
    
       for(int i=0; i<100; i++)
       {
         ArrayPuffer[i] = *(ArrayPointer+i);
       }
       ...  
    }
    

    Strukturen sind wirken da jedoch ziemlich umständlich.
    Gibt es da nicht etwas "schöneres"?



  • Achja, habe das oben gezeigt nicht getestet, der Compiler nimmt es jedoch an.



  • Wenn dein Compiler es schluckt, kann ich ja Schreibfehler ausschließen.

    Was ist ElementType? Wie sieht getVoidPointer aus?



  • Ups, habe falschen Code genommen.
    So sieht er richtig aus:

    struct _ElementTypA
    {
      float Element[3];
    }*ElementTypA;
    
    struct _ElementTypB
    {
      float Element;
    }*ElementTypB;
    
    ElementTypA = (_ElementTypA*)getVoidPointer();
    ElementTypB = (_ElementTypB*)getVoidPointer();
    
    schreibeArray(ElementTypA);
    schreibeArray(ElementTypB);
    
    template <class _ElementTyp> void schreibeArray(_ElementTyp* ElementTyp)
    {
       ElementTyp ArrayPuffer[100];
    
       for(int i=0; i<100; i++)
       {
         ArrayPuffer[i] = *(ArrayPointer+i);
       }
       ...  
    }
    

    Also ElementTyp, und nicht ElementType.

    getVoidPointer() verdeutlicht einfach das ich einen void-Zeiger zuweise.
    In Wirklichkeit wird der von einer Element-Typ spezifischen Funktion übergeben.



  • Raaahhh! Schon wieder ein Tippfehler:

    struct _ElementTypA
    {
      float Element[3];
    }*ElementTypA;
    
    struct _ElementTypB
    {
      float Element;
    }*ElementTypB;
    
    ElementTypA = (_ElementTypA*)getVoidPointer();
    ElementTypB = (_ElementTypB*)getVoidPointer();
    
    schreibeArray(ElementTypA);
    schreibeArray(ElementTypB);
    
    template <class _ElementTyp> void schreibeArray(_ElementTyp* ElementTyp)
    {
       _ElementTyp ArrayPuffer[100];
    
       for(int i=0; i<100; i++)
       {
         ArrayPuffer[i] = *(ArrayPointer+i);
       }
       ...  
    }
    

    So, jetzt sollte es stimmen.

    Keine Vorschläge für eine schönere Alternative zu den Strukturen?



  • Und dein Compiler soll das da geschluckt haben? Dann fehlen mir aber noch Infos. Was is ArrayPointer? Wo verwendest du den Parameter ElementTyp in der Funktion?



  • Arrr.... ArrayPointer war auch noch ein Relikt aus meinem ursprünglichen Code

    [code]
    struct _ElementTypA
    {
    float Element[3];
    }*ElementTypA;

    struct _ElementTypB
    {
    float Element;
    }*ElementTypB;

    ElementTypA = (_ElementTypA*)getVoidPointer();
    ElementTypB = (_ElementTypB*)getVoidPointer();

    schreibeArray(ElementTypA);
    schreibeArray(ElementTypB);

    template <class _ElementTyp> void schreibeArray(_ElementTyp* ElementTyp)
    {
    _ElementTyp ArrayPuffer[100];

    for(int i=0; i<100; i++)
    {
    ArrayPuffer[i] = *(ElementTyp+i);
    }
    ...
    }[code]

    Ob es jetzt endlich stimmt? 😉


Anmelden zum Antworten