Unterschiedliche Funktionszeiger in vector speichern



  • Hallo,

    ich arbeite derzeit mit dem C++Primer(5th Edition, Englisch) und bin gerade beim Thema Funktionszeiger.
    Ich denke, dass ich es halbwegs verstanden habe, bin aber bei einer Aufgabe unsicher, ob meine Lösung sinnvoll ist. Funktionieren tut sie auf jeden Fall, aber mir erscheint der Lösungsweg doch etwas umständlich.

    Aufgabe 6.55 (S. 250)
    Schreibe 4 Funktionen, die zwei ints addieren, subtrahieren, multiplizieren und dividieren. Speicher Funktionszeiger in einem vector.

    Meine Lösung:

    //Beispielfunktion add
    //subtract, multiply und divide sehen genau so aus
    int add(const int i, const int j)
    {
        return i + j;
    }
    
    int main()
    {
        int (*addptr)(int, int) = add;
        int (*subptr)(int, int) = subtract;
        int (*multptr)(int,int) = multiply;
        int (*divptr)(int,int) = divide;
    
        vector<int(*) (int, int)> vec;
        vec.push_back(addptr);
        vec.push_back(subptr);
        vec.push_back(multptr);
        vec.push_back(divptr);
        return 0;
    }
    

    Ich speicher ja jetzt jeden Funktionszeiger einzelnen in meinem vector. Bei 4 Pointern ist das ja nicht so aufwändig, aber wenn man eine große Anzahl speichern will, wird das ganze ja schon etwas länger und nerviger.

    Dadurch, dass die Zeiger ja alle auf eine andere Funktion verweisen, kann man die ja nicht einfach über eine for-Schleife hinzufügen.

    Wenn mir jemand einen Hinweis geben könnte, wie man das sinnvoller lösen könnte, wäre mir schon geholfen 🙂

    Grüße, möbius



  • Ich denke in deinem Fall musst du wirklich jede Funktion einzeln in den Vector einfuegen.

    Was du aber machen kannst ist folgendes:

    int main()
    {
        vector<int(*) (int, int)> vec;
        vec.push_back(add);
        vec.push_back(sub);
        vec.push_back(mult);
        vec.push_back(div);
        return 0;
    }
    


  • Ok, das ist unschön.
    Danke für den Hinweis, das war mir nicht wirklch bewusst, obwohl es eigentlich offensichtlich ist.



  • Ich lass mal einen Link auf Boost.Assign da. Da sieht das dann so aus:

    vector<int(*) (int, int)> vec;
    
    vec += add, sub, mult, div;
    

    Das wird allerdings dadurch erreicht, dass Operatoren von Standardbibliothekstypen überladen werden. Man sollte das also nur lokal einsetzen, um namespace std nicht überall zu verschmutzen. Damit meine ich, die Boost.Assign-Header nicht in anderen Headern einzubinden -- im Grunde sollte man es etwa so behandeln wie using namespace.



  • Und diese push_back() -Exzesse haben seit C++11 auch ein Ende:

    int main(){
      typedef std::vector<int(*)(int,int)> function_table;
      function_table funcs{add, sub, mult, div};
    }
    

  • Mod

    Furble Wurble schrieb:

    Und diese push_back() -Exzesse haben seit C++11 auch ein Ende:

    int main(){
      typedef std::vector<int(*)(int,int)> function_table;
      function_table funcs{add, sub, mult, div};
    }
    

    Wobei man noch den alten Trick aus Vor-C++11-Zeiten erwähnen sollte. Ist zwar bei weitem nicht so schön, aber besser geht's eben nicht:

    vector<foo> bar;
    {
      foo temp_array[] = {wert1, wert2, wert3);
      bar.assign(temp_array, temp_array + sizeof(temp_array)/sizeof(*temp_array));
    }
    
    // Oder:
    
    foo nicht_temp_array[] = {wert1, wert2, wert3);
    vector<foo> bar(nicht_temp_array, nicht_temp_array + sizeof(nicht_temp_array)/sizeof(*nicht_temp_array));
    


  • Danke, das ist zumindest schön kurz und übersichtlich 👍


Anmelden zum Antworten