void als template-parameter ungültig?



  • hallo

    ich hab mir frei nach http://www.newty.de/fpt/functor.html#functors
    einen allgemeinen functor gebastelt

    template< class TClass, typename TReturn, typename TArg>
    class Functor
    {
        public:
            typedef TReturn TClass::*Fpt(TArg);
    
            Functor( TClass* object, Fpt methode )
            {
                m_object = object;
                m_methode = methode;
            }
    
            TReturn operator()( TArg arg )
            {
                return (*m_object.*m_methode)( arg );
            }
    
        private:
            TClass* m_object;
            Fpt m_methode;
    };
    

    instanzierung so

    class ClassA
    {
    public:
        ClassB Methode1(int i) {...}
    //...
    };
    ClassA a;
    Functor<ClassA, ClassB, int> func( &a, &ClassA::Methode1 );
    func();
    

    aber das geht nicht 😞

    kann mir jemand helfen?
    danke



  • Hi,

    EDIT:*Achtung: Hab in dieser Post nur Mist geschrieben 🙂 Bitte nicht merken!*

    void kann nicht als Template-Parameter uebergeben werden. Nie. (void* schon)

    Um den Functor auch mit Member Functions ohne Rueckgabewert nutzen zu koennen, musst du ganz einfach eine zweite Version deines Funktors deklarieren, in der du TReturn weglaesst und ueberall void im Code dafuer einsetzt. Ungefaehr so:

    template< class TClass, typename TArg>
    class Functor
    {
        public:
            typedef void TClass::*Fpt(TArg);
    
            Functor( TClass* object, Fpt methode )
            {
                m_object = object;
                m_methode = methode;
            }
    
            TReturn operator()( TArg arg )
            {
                (*m_object.*m_methode)( arg );
            }
    
        private:
            TClass* m_object;
            Fpt m_methode;
    };
    

    Du kannst auch mal in den Code der Boost.Function adapters reinschauen http://www.boost.org/doc/html/function.html



  • ah, ein grund, funktionen nicht als void foo (void) zu deklarieren.
    void kann sehr wohl template-parameter sein, nur eben nicht funktions parameter, außer in der oben genannten art und weise.

    //das funktioniert
    template <class X>
    class Bar
    {
       typedef int (Foo::*FooPtr) (X);
    };
    
    template <>
    class Bar<void>
    {
       typedef int (Foo::*FooPtr) (void);
    };
    
    template class Bar<void>;
    
    //aber das nicht:
    template <class X>
    class Quux
    {
       typedef int (Foo::*FooPtr) (X);
    };
    
    template class Quux<void>;
    


  • typename schrieb:

    aber das geht nicht 😞

    Meine Glaskugel erzählt mir, dass in diesem Fall "geht nicht" gleichbedeutend ist mit einer Compilermeldung á la

    Missing parameter to Functor<typename1_, typename2_, typename3_>::operator()(typename3_) [with typename1_ = ClassA, typename2_ = ClassB, typename3_ = int]
    

    oder so ähnlich. Du hast deinen functor-operator() so definiert dass er einen Parameter vom Typ TArg (in diesem Falle int) nimmt, hast ihm aber keinen gegeben. Versuchs mal mit func(4) oder sowas nettem...



  • @queer_boy
    Stimmt, ich verneige mich 🙂 Ich hatte schonmal aehnlichen Code und aehnliche Probleme und hab einfach ganz boese verallgemeinert. Danke fuer die Richtigstellung.

    @pumuckl
    Ich glaube der Code war nur examplarisch gezeigt um zu verdeutlichen was typename gerade macht. Ich glaube nicht, dass er die Parameter vergessen hat. Er hat in seinem Code auch kein void als Template-Parameter.



  • danke erstmal

    der code oben will sowieso nicht funktionieren, auch wenn ich mit int und func(4) mache.
    die fehlermeldung war etwa "undefined reference to local function" oder so.
    mit void hiess es: "ungültiger parameter: void"

    habs jetzt wieder gelöscht



  • sry hab was vergessen
    in diese zeile springt der cursor:

    return (*m_object.*m_methode)( arg );
    


  • Naja, dann ueberleg doch mal was da steht, wenn TArg void ist:

    TReturn operator()( void arg )  //eine void-variable names arg O.O ...
            {
                (*m_object.*m_methode)( arg ); //wird hier an die methode uebergeben, die keine Parameter erwartet - das kann nicht gutgehn
            }
    


  • pumuckl schrieb:

    eine void-variable names arg O.O ...
    wird hier an die methode uebergeben, die keine Parameter erwartet - das kann nicht gutgehn

    stimmt
    dann müsst ich ne dummy klasse machen. ich vergess es wieder.


Anmelden zum Antworten