function-pointer problem



  • vielen dank, die [4] habe ich total übersehen danke.

    ich stehe erneut auf dem schlauch: warum kann ich nun die ausgabe nicht
    bringen:

    #include <iostream>
    #include <vector>
    
    typedef int (*pfcn)(int,int);
    
    int fcn1(int a, int b) { return a + b; }
    int fcn2(int a, int b) { return a - b; }
    int fcn3(int a, int b) { return a * b; }
    int fcn4(int a, int b) { return a / b; }
    
    int main(int argc, char** argv)
    {
      std::vector<pfcn> fcn_vec;
      fcn_vec.push_back(&fcn1);
      fcn_vec.push_back(&fcn2);
      fcn_vec.push_back(&fcn3);
      fcn_vec.push_back(&fcn4);
    
      std::vector<pfcn>::iterator it;
      for(it = fcn_vec.begin(); it != fcn_vec.end(); it++)
         std::cout << it->second(2,5) << std::endl;
    
      return 0;
    }
    
    main.cpp: In Funktion »int main(int, char**)«:
    main.cpp:21:23: Fehler: Abfrage des Elementes »second« in »* it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator-> [mit _Iterator = int (**)(int, int), _Container = std::vector<int (*)(int, int)>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::pointer = int (**)(int, int)]()«, das vom Nicht-Klassentyp »int (*)(int, int)« ist
    


  • Was soll denn it->second sein?

    So:
    std::cout << (*it)(2,5) << std::endl;



  • 😞 danke Dir

    3te und letzte Frage: wie könnte ich obigen code mit einem std::vector realisieren wenn ich jetzt eine zusätzlich fcn5 einführe deren signatur so aussieht:

    float fcn5(float a, int b)

    ? also wenn ich die typen mische?



  • Pack Funktionszeiger mit anderer Signatur in einen weiteren vector.



  • Pack Funktionszeiger mit anderer Signatur in einen weiteren vector.

    ist das die einzige möglichkeit oder ginge es auch anders? Ich frage nur aus Interesse.



  • also wenn ich die typen mische?

    Gar nicht. Du kannst nicht zwei verschiedene Typen in einem Container halten. Macht auch nicht viel Sinn. Hier könntest du den Effekt durch eine Hilfsklasse erzielen.



  • Nein, ein Funktionszeiger mit einem float ist ein anderer Typ und kann nicht im Vektor abgelegt werden.



  • Sone schrieb:

    Du kannst nicht zwei verschiedene Typen in einem Container halten. Macht auch nicht viel Sinn. Hier könntest du den Effekt durch eine Hilfsklasse erzielen.

    Am Ende musst du ja irgendwie wissen, welchen Typ der aus dem Container entnommene Wert hat. Der Container wird's dir nicht sagen, da er nur eine Art von Typ aufnimmt, also sollte der Wert selbst von einer Klasse 'umschlossen' werden, die es dir sagt.
    Ein Beispiel ist boost::any.



  • Youka schrieb:

    Ein Beispiel ist boost::any.

    Allerdings kann man die meisten Fälle, in denen man boost::any zu benötigen glaubt, sauberer lösen. Zum Beispiel durch dynamische Polymorphie.



  • Nexus schrieb:

    Youka schrieb:

    Ein Beispiel ist boost::any.

    Allerdings kann man die meisten Fälle, in denen man boost::any zu benötigen glaubt, sauberer lösen. Zum Beispiel durch dynamische Polymorphie.

    Korrigiere mich bitte, aber läuft das im Endeffekt nicht alles auf Type-Erasure heraus?



  • Der Unterschied ist allerdings, dass man im Fall von boost::any den genauen dynamischen Typen wissen muss, um mit dem Objekt etwas anfangen zu können.



  • krümelkacker schrieb:

    Der Unterschied ist allerdings, dass man im Fall von boost::any den genauen dynamischen Typen wissen muss, um mit dem Objekt etwas anfangen zu können.

    Man muss wissen, welche dynamischen Typen es haben könnte.



  • Sone schrieb:

    Nexus schrieb:

    ...Zum Beispiel durch dynamische Polymorphie.

    Korrigiere mich bitte, aber läuft das im Endeffekt nicht alles auf Type-Erasure heraus?

    So ist es. Der Wert wird auf dem Heap gelegt und somit der Typ versteckt. Die Zuweisung mit Templates erlaubt jeglichen Eingabetyp, problematisch ist lediglich die Ausgabe. Dazu muss bei Zuweisung auch der Typ gespeichert werden und abgefragt werden können, um den internen Zeiger wieder richtig zu casten.

    Idee hinter boost::any



  • Sone schrieb:

    Man muss wissen, welche dynamischen Typen es haben könnte.

    Und alle durchprobieren, oder wie?

    Sone schrieb:

    Korrigiere mich bitte, aber läuft das im Endeffekt nicht alles auf Type-Erasure heraus?

    Nein. Dynamische Polymorphie alleine ist noch keine Type Erasure.

    Mit Laufzeitpolymorphie kannst du eine virtuelle Funktion aufrufen, die intern den richtigen dynamischen Typ dispatcht. Bei boost::any muss die Fallunterscheidung explizit erfolgen, was dem Grundgedanken von Polymorphie gerade widerspricht. Deshalb ist boost::any auch nur für Spezialfälle brauchbar, genau wie dynamic_cast .


Anmelden zum Antworten