template <class T : pulbic BaseClass> ... wie funktioniert das richtig?



  • Hi, ich möchte eine Template Funktion schreiben, die als Template Argument eine Klasse nimmt, die von einer bestimmen Basis Klassen erben muss.
    Wie macht man das richtig. Ich habe diese schreibweise einfach mal intuitiv gewählt:

    class Camera
    {
        /* ... */
        virtual void Move() = 0;
    };
    
    class MyCam : public Camera
    {
        /* ... */
        void Move();
    };
    
    template <class T : public Camera> T* CreateCamera() // !!!
    {
        T* Cam = new T();
        Cam->Move();
        return Cam;
    }
    
    MyCam* c = CreateCamera<MyCam>();
    

    Wie funktioniert das richtig?



  • Hallo LukasBanana,

    du brauchst/kannst in C++ den Template-Parametern keine Typinformationen mitgeben.

    template <class T>
    T* CreateCamera(){
        T* Cam = new T();
        Cam->Move();
        return Cam;
    }
    

    EDIT: Also wenn sie die Bedingungen nicht erfüllt, kriegst du halt einen Kompilierfehler...

    EDIT2: Jetzt kannst du natürlich auch mit 'Nicht-Camera'-Typen, die einen Default-Konstruktor und eine Funktion Move() haben, die Funktion aufrufen.
    Falls du das wirklich verhindern willst - worin ich atm keinen Sinn sehe - kannst du etwas machen wie:

    void check_if_cam(Camera& cam){}
    
    template <class T>
    T* CreateCamera(){
        T* Cam = new T();
        check_if_cam(*Cam);
        Cam->Move();
        return Cam;
    }
    

    Gruß,
    XSpille



  • Alles klar danke, dann lass ich die Überprüfung (check_if_camera) einfach weg.



  • LukasBanana schrieb:

    Hi, ich möchte eine Template Funktion schreiben

    Funktions-Template heißt das. Es ist keine Funktion. Es ist ein Template. Eine Schablone für Funktionen. Funktions-Template.

    LukasBanana schrieb:

    , die als Template Argument eine Klasse nimmt, die von einer bestimmen Basis Klassen erben muss.

    Wo äußert sich das mit dem "muss"?

    LukasBanana schrieb:

    Wie macht man das richtig. Ich habe diese schreibweise einfach mal intuitiv gewählt:

    class Camera
    {
        /* ... */
        virtual void Move() = 0;
    };
    
    class MyCam : public Camera
    {
        /* ... */
        void Move();
    };
    
    template <class T : public Camera> T* CreateCamera() // !!!
    {
        T* Cam = new T();
        Cam->Move();
        return Cam;
    }
    
    MyCam* c = CreateCamera<MyCam>();
    

    Wie funktioniert das richtig?

    Wenn T kein Move() anbietet, dann kompiliert das so einfach nicht und gut ist. Man kann Funktions-Templates mit Tricks "beschränken". Ich sehe in Deinem Fall aber nicht den Nutzen.

    Mal ein Beispiel:

    template<class T>
    class stupid_pointer {
      T* ptr_;
    public:
      stupid_pointer(T* p) : ptr_(p) {}
    
      T* get() const {return ptr_;}
    
      template<class U>
      stupid_pointer(stupid_pointer<U> p
        [b],typename boost::enable_if<[/b]
          [b]boost::is_convertible<U*,T*>[/b]
        [b]>::type* =0[/b]
      ) : ptr_(p.get()) {}
    
      T* operator->() const {return p;}
      T& operator*() const {return *p;}
    };
    

    Sinvoll ist das aus zwei Gründen:
    - Fehler früher abfangen
    - Überladungsmenge klein halten


Anmelden zum Antworten