Workaround für virtual function templates !



  • Ich habe die Idee mal in einem anderen Forum diskutiert, siehe
    http://www.gamedev.net/community/forums/topic.asp?topic_id=424879

    Basierend auf einem Vorschlag von einem Member dort komme ich auf die folgende, noch elegantere Version.

    DelegatorBase<Missile>         DelegatorBase<LaserGun>
                                         \         / 
                                          \       / 
        XWing                           SpaceshipBase                        BWing
          | \             ______________/   /   \   \_________________       / |
          |  \           /                 /     \                    \     /  |
          |   \_________/______           /       \                 ___\___/   |
          |            /       \         /         \               /    \      |
          |           /         \       /           \             /      \     |
     DelegatorT<XWing, Missile>  \     /    DelegatorT<BWing, Missile>    \    |
             \                    \   /             |                      \   |
              \      DelegatorT<XWing, LaserGun>    |     DelegatorT<BWing, LaserGun>   
               \             /                      |           / 
                \           /                       |          / 
              SpaceshipT<XWing>                  SpaceshipT<BWing>
    
    //                                                         general framework
    //---------------------------------------------------------------------------
    
    template<struct Weapon> struct DelegatorBase {
        virtual void hit_v(Weapon*)=0;
    };
    
    struct SpaceshipBase :
        DelegatorBase<Weapon_1>,  // can be achieved in code size O(1)
        ...,
        DelegatorBase<Weapon_k>
    {
        template<struct Weapon> hit() {hit_v((Weapon*)0);}
    };
    
    template<struct ShipType, struct Weapon> struct DelegatorT :
        virtual ShipType,
        virtual SpaceshipBase
    {
        virtual void hit_v(Weapon*) {hit_impl<Weapon>();}
    };
    
    template<struct ShipType> struct SpaceshipT :
        DelegatorT<ShipType, Weapon_1>,  // can be achieved in code size O(1)
        ...,
        DelegatorT<ShipType, Weapon_k>
    {
    };
    
    //                                                       specific spaceships
    //---------------------------------------------------------------------------
    
    struct Type_XWing {
        template<struct Weapon> void hit_impl() {...}
    };
    
    struct Type_StarDestroyer {
        template<struct Weapon> void hit_impl() {...}
    };
    
    //                                                          specific weapons
    //---------------------------------------------------------------------------
    
    struct Missile {...};
    
    template<int n> struct RailgunT  // Railgun type n
    {...};
    
    //                                                                     usage
    //---------------------------------------------------------------------------
    
    void main() {
        SpaceshipBase* spaceship = new SpaceshipT<Type_XWing>();
        spaceship->hit<Missile>();
    }
    

    Vorteil: Beim Implementieren der Schiffstypen muss man sich nicht mehr mit der komplizierten Architektur herumschlagen.


Anmelden zum Antworten