Template erstellen

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von T3c4n01d, 10. März 2006 .

Schlagworte:
  1. 10. März 2006
    wie kann ich aus folgendem Programmcode mit function-overloading ein Template basteln?

    Ich probiere jetzt schon stundenlang rum...

    template <class T>
    ind find(T f, char* wert, int & anz){} ????

    ich blick das irgendwie nicht mit den Templates.


    Code:
    const int maximum=5;
    
    typedef int ind;
    
    typedef char* Feld[maximum];
    
    
    
    ind find(Feld f, char* wert, int & anz){
    ind ret=-1;
    anz=0;
    
     for (int i=0; i!=maximum; i++){
    
     int j=strcmp(f[i], wert);
     if (j==0){ret=i;anz++;}
    
     }
     return ret;
    }
    
    ind find(Feld f, int wert, int & anz){
     ind ret;
     char b[50];
     ret=find(f, itoa(wert, b, 10), anz);
    
    return ret;
    }
    THX a lot
    der 10er für hilfreiche Antworten ist auf jeden Fall sicher!
     
  2. 10. März 2006
    nen Template benutzt man ja, wenn es eine Funktion für verschiede Parameter-Datentypen gibt.

    Vom Prinzip her wäre das in deinem Fall (wenn ich das richtig sehen, dass du die selbe Funktion für int und char* nutzen willst)

    template <class T>
    ind find(Feld f, T wert, int& anz){}

    Aber die Funktionen der unterschiedlichen Datentypen unterscheiden sich ja doch schon recht stark.
    Erklär mal genauer, was du da machen willst und was du dir davon erwartest.
     
  3. 10. März 2006
    Also:

    in einem Feld werden Werte vom Typ char* gespeichert.
    Code:
    Char* Feld[maximum];
    zum Test habe ich 2 Felder besetzt mit:
    Code:
     Feld f1={"3","2","0","2","-10"};
     Feld f2={"abc1","ab2","abcd3","abx4","yxc5"};
    
    Jetzt soll mit den Funktion
    Code:
     
    char* suchstring="abx4";
    find(f2,suchstring,anzahl);
    
    Als Rückgabe wird ein Index vom Feld f2 geliefert. (Hier 3) und die anzahl wie oft der suchstring vorkommt (Hier 1).


    die 2. find-Funktion soll das gleiche machen nur mit int Werten. Dazu wandle ich die int-Werte in einen char* um:
    Code:
    itoa(wert, b, 10);
    und rufe dann die 1 find-Funktion auf.

    Bei der Suche in Feld1:
    Code:
     
    int suchstring=2;
    find(f1,suchstring,anzahl);
    
    Die Rückgabe ist hier: 3 und 2 (3 weil die Schleife komplett durchlaufen wird und der index des letzten gefundenen Wertes zurückgeliefert wird und 2 weil das Element 2 mal vorkommt.

    Und das ganze soll dann als Template realisiert werden

    THX

    [edit] Wenn das Element nich vorhanden ist wird eine -1 zurückgeliefert.[/edit]
     
  4. 11. März 2006
    Wenn du schon in C++ schreibst, kannst du doch gleich auch die vorgefertigten Algorithmen von der STL nehmen? Oder spricht da etwas dagegen?

    Diese sind natürlich auch mit Templates realisiert. D.h. du kannst dir die jeweilligen Funktionen anschauen, in dem du in dein Include-Ordner deines Compilers / IDE gehst und dort die entsprechende algorithm-Datei öffnest.

    Die STL ist nicht umsonst geschrieben und erleichtert einiges.

    Dein Code würde dann so aussehen (es ist kompilierfähig):

    Code:
    #include <algorithm>
    #include <iostream>
    #include <string>
    
    int main() {
     // unsere Test Arrays, evtl. mit Vektoren besser zu lösen
     int numbers[] = { 3, 2, 0, 2, -10 };
     // Strings sind einfach handlicher und bequemer
     std::string words[] = { "abc1", "ab2", "abcd3", "abx4", "yxc5" };
    
     // mit Hilfe der Algorithmen aus STL
     // bei Vektoren, Iteratoren: vec.begin(), vec.end()
     
     // die Vorkommnisse zählen
     std::cout << "Zahl 2 kommt " << std::count(numbers, numbers + 5, 2) << "-mal vor." << std::endl;
    
     // den Index berechnen, falls nichts gefunden wurde, bekommst du den letzten Index + 1 zurück
     // wir müssen die Entfernung vom Anfang bis zum gefundenen Wort ermitteln
     std::cout << "Der Index von \"abx4\" ist " << std::distance(words, std::find(words, words + 5, "abx4")) << "." << std::endl;
    }
    
    Du siehst, dass die Anzahl der Vorkommnisse und die Indexberechnung in eigene Funktionen getrennt sind.
     
  5. 11. März 2006
    Das ist ja alles schön und gut. Allerdings geht es mir (in meiner Ausbildung) darum diese Datenstrukturen selbst zu entwickeln.

    Trotzdem THX für die Mühe!!!
     
  6. 11. März 2006
    Okay, so etwas hab ich mir schon beinahe gedacht.

    Ich hab mir mal kurz die Mühe gemacht und deinen Code in ein Template gewandelt.

    Schau es dir an:

    Code:
    #include <iostream>
    #include <string>
    
    template <typename T, typename U>
    int find(T& array, U value, int& count) {
     int result = -1;
    
     for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
     if (array[i] == value) {
     result = i;
     ++count;
     }
    
     return result;
    }
    
    int main() {
     std::string words[] = { "abc1", "ab2", "abcd3", "abx4", "ab2" };
     
     int count = 0, index = find(words, "ab2", count);
    
     std::cout << "Anzahl: " << count << ", Index: " << index << std::endl;
    }
    
    Ist das hilfreich?

    Versuche jedoch in Zukunft die STL zu benutzen. Das Rad muss nicht immer neu (und evtl. schlechter) erfunden werden.

    Ergänzung: Die STL verwendet anstatt den Typ int ptrdiff_t. Dieser Typ ist in der Header <cstddef> definiert. Je nach Implementierung kann er üblicherweise int oder long sein.
     
  7. 11. März 2006
    Ich hatte es mittlerweile so gelöst:

    Code:
    const int maximum=5;
    
    typedef int ind;
    
    typedef char* Feld[maximum];
    
    #include <iostream.h>
    #include <string.h>
    #include <typeinfo.h>
    
    template <class T>
    ind tfind(Feld f, T wert, int& anz){
     find(f,wert,anz);
     };
    
    
    ind find(Feld f, char* wert, int& anz){
    
    ind ret=-1;
    anz=0;
    
     for (int i=0; i!=maximum; i++){
    
     int j=strcmp(f[i], wert);
     if (j==0){ret=i;anz++;}
    
     }
    
    return ret;}
    
    ind find(Feld f, int wert, int& anz){
    
    ind ret=-1;
    anz=0;
     char b[50];
     char* temp=itoa(wert, b, 10);
    
     for (int i=0; i!=maximum; i++){
    
     int j=strcmp(f[i], temp);
     if (j==0){ret=i;anz++;}
    
     }
     return ret;
    }
    
    Keine Ahnung ob das stimmt. Es sollte aus dem function-overloading ein template erstellt werden.

    THX@all.
     
  8. 11. März 2006
    Ehm, hast du dir eigentlich meinen Code auch mal angeschaut??
    Das was du da machst hat wirklich gar nichts mehr mit Templates zu tun.
    Du weißt schon, wozu es Templates gibt und wann man sie einsetzt?

    Ich kommentiere mal ein bisschen dein Code.

    Code:
    const int maximum=5; // muss nicht sein, siehe mein Code: sizeof(array) / sizeof(*array) = Größe eines Arrays
    
    typedef int ind; // das musst mir wirklich mal erklärn *gg* was ist an inD so toll? ;)
    
    typedef char* Feld[maximum]; // ob ein typedef sinnvoll wäre, lässt sich streiten
    
    #include <iostream.h> // okay, erster gravierender Fehler... lass die Endung weg, der C++ Standard 98 sagt was anderes
    #include <string.h> // siehe oben
    #include <typeinfo.h> // wozu das?
    
    template <class T> // das Tempalte kannst du ganz weglassen, wozu brauchst du es denn?
    ind tfind(Feld f, T wert, int& anz){ // der Kompiler findet doch sowieso die richtige Version, dank Funktionsüberladung
     find(f,wert,anz);
     };
    
    
    ind find(Feld f, char* wert, int& anz){ // joa, char*'s machen Probleme... bin immer noch dagegen, die Anzahl als Referenz zu übergeben
    
    ind ret=-1; // hast du mal an Codeeinrückung gedacht?
    anz=0; // der Code wird so viel übersichtlicher
    
     for (int i=0; i!=maximum; i++){
    
     int j=strcmp(f[i], wert); // wieso ablaagern, tue das Ergebnis doch gleich in die if-Anweisung hinein
     if (j==0){ret=i;anz++;} // aufteilen schadet nicht
    
     }
    
    return ret;}
    
    ind find(Feld f, int wert, int& anz){ // das ist ja mal was.. wieso machst du dir das alles so kompliziert
    
    ind ret=-1;
    anz=0;
     char b[50];
     char* temp=itoa(wert, b, 10); // Ohje, wieso machst du denn das?? Du musst doch gar nicht umwandeln
    
     for (int i=0; i!=maximum; i++){
    
     int j=strcmp(f[i], temp); //hmm, f[i] == wert - ist das nicht einfacher so?! wieso alles in char*???
     if (j==0){ret=i;anz++;} // s.o.
    
     }
     return ret;
    }
    
    Was bei meinem Code oben noch zu bemängeln wäre, ist, dass er nicht für C-Strings konziptiert worden ist und somit mit denen nicht umgehen kann. Leider kann man Funktionen nicht partiell spezialisieren. Les dir mal das Kapitel über Templates nochmal durch, damit du verstehst, wann du sie anwenden musst und wann du es lassen kannst. Schau dir mein Code von oben nochmal an. Das ist eine generische Version der find() Funktion.

    Nochmals zu den C-Strings zurück. Leider kann man diese nicht mit dem Operator== vergleichen, sondern nur mit den Funktionen aus <cstring>, also strcmp(), so wie du es ja getan hast. Du musst daher diese Version überladen. Da der Wert (bei mir value) als Typ dann den const char-Zeiger bekommt, ist die Überladung generell möglich.

    Die überladene Funktion sieht dann so aus:

    Code:
    int find(const char** array, const char* value, int& count) {
     int result = -1;
    
     for (int i = 0; i <= sizeof(*array) / sizeof(**array); ++i)
     if (strcmp(array[i], value) == 0) {
     result = i;
     ++count;
     }
    
     return result;
    }
    
    Du hättest dieses Problem nicht, wenn du gleich anfängst mit std::string zu arbeiten. String bietet dir nämlich gleich den tollen Vergleichsoperator an, in dem er ihn überladet. Außerdem musst du dir keien Gedanken über das Speichermanagement machen.
     
  9. 12. März 2006
    so sieht die Aufgabe aus:

    Deklarieren und definieren Sie zwei Prozeduren (Prozedurname find) die in einem Feld einen Wert (wert) suchen. Benutzen Sie "function overloading". Der Index (ind) des gefundenen Wertes soll zurückgegeben werden. Index ist –1, falls der Wert im Feld nicht vorhanden ist. Die Felder enthalten Werte vom Typ int und C-Zeichenketten.....Geben Sie jeweils die Werte von Index und Anzahl aus! Lösen Sie die Aufgabe mit Funktions-Templates (Prozedurname tfind).
    Hinweis: Verwenden Sie die vorherige Lösung mit notwendigen Veränderungen!
    Es wird ohne VCL usw. gearbeitet.

    Oder soll das Template für die Felder erstellt werden? Irgendwo hab ich einen Denkfehler!?


    Ich würde gerne noch ganz andere Sachen machen. Aber der Dozent mags in seiner alten Schreibweise und das ist Vorraussetzung für die spätere Klausur.

    [edit]
    So ich habs jetzt...

    Ich hätte da nur noch eine Frage zu folgendem Code-Schnipsel:
    Code:
    i <= sizeof(*f)
    Warum muss f dereferenziert (*f) werden um den Vergleichsoperator für strings anzuwenden?

    [/edit]
     
  10. 16. März 2006
    ich weiss nicht ob es sinnvoll ist in einem kleien projekt stl zu verwenden. für anfänger sorgen sie nur zur verwirrung, aber ich kenne da ein gutes tutorial

    C++ Standard Bibliothek
    Template Spezialitäten
    STL Container

    ich hoffe, dass das jemandem weiterhelfen kann.
     
  11. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.