virtual foo und template foo in einer klasse



  • Hallo Leute!

    Ich habe eine Klasse mit 2 member funktionen:

    class Test
    {
      template<class T>
      void foo(T t)
      {
        //do something
      }
    
      void foo(bar& t)
      {
        //do something
      }
    };
    

    das sollte ja passen. wenn
    foo(bar());
    aufgerufen wird, wird die non template version gewaehlt, andernfalls die template version.

    das funktioniert doch auch bei
    foo(BaseOfBar());
    oder?

    naja, das problem ist aber nun, dass ich ueber einen template parameter steuern will, ob die funktionen virtual sind, oder nicht.

    class allVirtual
    {
    public:
      template<class T>
      void foo(T t)
      {
        bar = convert_to_bar(t);
        foo(bar);
      }
    
      virtual void foo(bar& t) = 0;
    };
    
    class noVirtual
    {
    };
    

    doch das klappt nicht.

    ist irgendwie auch logisch, dass es nicht klappt 😞

    nur wie kann ich etwas aehnliches erreichen? mir waere sehr wichtig, dass foo() den namen behaelt.

    der sinn ist der, dass man imm p->foo(); schreiben kann, ohne sich darum kuemmern zu muessen, ob man jetzt das template foo oder das andere aufruft -> die non template version arbeitet natuerlich mit virtual funktionen und ist deshalb langsamer.

    aber das sollte den client code eigentlich nicht kuemmern. denn ich lege einmal fest, ob ich Test virtuell verwende oder nicht - und der code sollte gleich bleiben...

    irgendjemand eine idee wie man das machen koennte??



  • du meinst sicher nicht

    Shade Of Mine schrieb:

    das funktioniert doch auch bei
    foo(BaseOfBar());

    sondern
    foo(DerivedFromBar());
    nicht?
    laut standard (13.3.1p7/14.8.3) wird jedes function template zuerst mit dem typ des übergebenen arguments instanziiert und dann als candidate function mit den anderen verglichen. das heißt aus den funktionen wird. mit T=bar wird daraus

    //die template-funktion
    void foo (bar)
    //und
    void foo (bar&)
    

    laut 13.3.3 ist eine non-template function in dem falle vorzuziehen.
    mit DerivedFromBase sieht es so aus:

    //template
    void foo (DerivedFromBar) //ups, passt ja perfekt
    //und
    void foo (bar&)
    

    };
    [/cpp]

    erklär mir nochmal, was du mit allVirtual und noVirtual bezwecken willst..
    irgendwie fehlt mir da noch der durchblick.

    willst du durch das an foo übergebene argument festlegen, ob virtual void foo oder nur void foo aufgerufen wird?



  • thx, aber ich habe dank bashar das problem schon geloest:

    ich habe nun in allVirtual keine virtuelle funktionen mehr, sondern foo ist nicht virtual.

    in foo rufe ich dann die virtual methode 'fooImpl()' auf - welche die arbeit dann macht.

    das mit dem BasOfBar() ist doof, habe deswegen auch das zweite foo zu einem template gemacht:

    template<class T>
    void foo(Bar<T> t)
    {
    }
    

    Bar<T> hat als Basisklasse BaseOfBar
    und so geht es dann 🙂

    fooImpl() erwartet ein BaseOfBar const& und das bekommt es dann auch.

    der sinn ist der:
    policy basierende virtualitaet.

    es gibt eine zentrale klasse die viel verwaltet. bei kleinen programmen will man diese klasse vielleicht garnicht global zugaenglich machen. bei anderen programmen reicht ein
    typedef MyClass<Policies> MySingleton;
    aus -> alles schoen statisch, ohne runtime kosten

    aber manchmal kommt man drauf, dass man erst zur laufzeit weiss, welche Policies MyClass denn am besten passen wuerden. da braucht man dann runtime polymorphie.

    in diesem fall wird MyClass dann von allVirtual abgeleitet und hat nur noch virtuelle methoden -> man kann sie polymorph verwenden!


Anmelden zum Antworten