Klasse mit Operator() als Funktion übergeben



  • Gegeben sind folgende Klassen, Funktionen und Header (Ein bisschen gekürzt)

    MEMap.h :

    class GameMap
    	{
    	public:
    	GameMap(void (*generator)(MapPoint*** ,int* max_x,int* max_y)); 
    	~GameMap();
    
    	MapPoint* operator() (int x,int y);	
    	void set (Mapobj* ,int x, int y);	
    	void clear (Mapobj* , int x, int y);
    	int get_xdim(); 
    	int get_ydim(); 
    
    	private:/*interessiert vermutlich nicht*
            }
    

    sowie mein als Testprogramm gedachtes File MysteriesExplorer.cc :

    #include "MEvisual.h"
    #include "MEMap.h"
    #include "MEMapobjects.h"
    #include <iostream>
    #include <string>
    
    class SingleRoomGenerator
    	{
    	public:
    	SingleRoomGenerator (int x, int y)
    		{
    		this->x=x;
    		this->y=y;
    		}
    
    	void operator() (MapPoint*** mp, int* dim_x, int* dim_y)
    		{
    		/*Interessiert vermutlich nicht*/
    		}
    
    	private:
    	int x;
    	int y;
    	};
    
    int main()
    	{
    	SingleRoomGenerator gen(10,10);
    	GameMap* gm=new GameMap(&gen);
    	GameMapRepresentation gmr=new GameMapRepresentation(gm);
    	gmr->start();
    	}
    

    Die MEMap.cc (Deren Header ja die MEM.h ist) kompiliert ohne Warnung mit -Wall
    Beim Versuch, die MysteriesExplorer.cc zu kompilieren, erhalte ich aber folgende Fehlermeldung:

    MysteriesExplorer.cc: In function ‘int main()’:
    MysteriesExplorer.cc:43:30: error: no matching function for call to ‘GameMap::GameMap(SingleRoomGenerator*)’
    MysteriesExplorer.cc:43:30: note: candidates are:
    In file included from MEvisual.h:11:0,
                     from MysteriesExplorer.cc:1:
    MEMap.h:49:2: note: GameMap::GameMap(void (*)(MapPoint***, int*, int*))
    MEMap.h:49:2: note:   no known conversion for argument 1 from ‘SingleRoomGenerator*’ to ‘void (*)(MapPoint***, int*, int*)’
    MEMap.h:41:7: note: GameMap::GameMap(const GameMap&)
    MEMap.h:41:7: note:   no known conversion for argument 1 from ‘SingleRoomGenerator*’ to ‘const GameMap&’
    

    Ich vermute einmal, dass ich nicht in der Lage bin, meine Klasse SingleRoomGenerator als Funktionszeiger zu übergeben. Diese soll aber eigentlich als Funktion wirken (Dazu ist in ihr ja auch der Operator () überladen worden)
    Was mache ich aber dabei verkehrt?



  • nutze duck-typing:

    template<typename CallableT>
    GameMap(CallableT Callable);
    

    nun kannst du funktionszeiger, lambdas und funktoren übergeben. innerhalb des konstruktors behandelst du Callable genau gleich wie generator vorher. du gehst einfach davon aus dass Callable die syntax Callable(...) mit den richtigen argumenten unterstützt. wenn es das nicht tut, dann gibt es eine fehlermeldung.


  • Mod

    Und falls du das Funktionsobjekt abspeichern musst, nimm eine Membervariable mit std::function , wie std::function<void(MapPoint*** ,int* max_x,int* max_y)> .



  • Wer hat mich letztens noch einen Drei-Sterne-Programmier genannt?



  • GameMap kann ich leider nicht generisch entwerfen. Ich habe das Problem, dass ich mehrmals (Wenn auch selten) eine GameMap an derselben Stelle im Programm erstellen will, dies aber mit verschiedenen Generatoren. Damit wäre meine Typisierung zur Laufzeit inkonsistent.

    Aber der Tip mit std::function brachte mich auf std::mem_fn.
    (Beides Elemente, die ich bis eben noch nicht kannte 😃 )
    Damit werde ich es mal versuchen 😃



  • Tigerle schrieb:

    GameMap kann ich leider nicht generisch entwerfen. Ich habe das Problem, dass ich mehrmals (Wenn auch selten) eine GameMap an derselben Stelle im Programm erstellen will, dies aber mit verschiedenen Generatoren. Damit wäre meine Typisierung zur Laufzeit inkonsistent.

    uhm, nein eigentlich nicht:

    std::unique_ptr<GameMap> MyMap;
    if(UserInput == 42)
    {
    	MyMap.reset(new GameMap(GeneratorByFile("uvw.xyz"))); // Funktor
    }
    else
    {
    	MyMap.reset(new GameMap(&GeneratorByAlgorithm)); // Funktion
    }
    


  • Tigerle schrieb:

    GameMap kann ich leider nicht generisch entwerfen. Ich habe das Problem, dass ich mehrmals (Wenn auch selten) eine GameMap an derselben Stelle im Programm erstellen will, dies aber mit verschiedenen Generatoren. Damit wäre meine Typisierung zur Laufzeit inkonsistent.

    Du sollst ja auch nicht die Klasse generisch machen, sondern den Konstruktor.


Log in to reply