Pointer auf Objektmethoden und andere Probleme



  • Hi was mache ich falsch?

    #include <iostream>
    template <class T, class ObjectT, class FunctionT>
    struct obj_caller;
    
    template <class T>
    struct basic_object
    {
        inline T const& derived() const
                { return *static_cast<T const*>(this); }
    
        template <class ObjectT, class FunctionT>
            inline obj_caller<T, ObjectT, FunctionT> operator()(ObjectT *obj, FunctionT *v) const
            {
                return obj_caller<T, ObjectT, FunctionT>(derived(), obj, v);
            }
    };
    
    template <class T, class ObjectT, class FunctionT>
    struct obj_caller : public basic_object<obj_caller<T,ObjectT, FunctionT> >
    {
        T caller;
        ObjectT *callee;
        FunctionT *function;   
    
        obj_caller(const T &m, ObjectT *c, FunctionT *f) : caller(m), callee(c), function(f) {}
    
        void exec()
        {
            caller.do_call(callee,function);
        }
    };
    
    template <char v>
    struct example : public basic_object<example < v> >
    {
        template <class ObjectT, class FunctionT>
            inline  void do_call(ObjectT *obj, FunctionT* f)
            {
                obj->*f(v);
            }
    
    };
    
    struct receiver 
    {
        example<'a'> sender;
    
        void callme(char value) 
        {
            std::cout << "Got called with " << value << std::endl;
        }
    
        void run()
        {
            obj_caller<example<'a'>, receiver, void (receiver::*)(char) > foo = sender (this, &receiver::callme);
            foo.exec();
    
            sender(this, &receiver::callme).exec();
        }
    };
    
    int main()
    {
        receiver obj;
        obj.run();
        return 0; 
    }
    

    gcc 3.3 sagt dazu:

    basic_object.cpp: In member function `void receiver::run()':
    basic_object.cpp:57: no match for call to `(example<'a'> ) (receiver* const, 
       void (receiver::*)(char))'
    basic_object.cpp:60: no match for call to `(example<'a'> ) (receiver* const, 
       void (receiver::*)(char))'
    basic_object.cpp: In member function `void example<v>::do_call(ObjectT*, 
       FunctionT*) [with ObjectT = receiver, FunctionT = void (receiver::*)(char), 
       char v = 'a']':
    basic_object.cpp:30:   instantiated from `void obj_caller<T, ObjectT, FunctionT>::exec() [with T = example<'a'>, ObjectT = receiver, FunctionT = void (receiver::*)(char)]'
    basic_object.cpp:58:   instantiated from here
    basic_object.cpp:41: `f' cannot be used as a function
    

    icc 7 ist der Meinung das:

    basic_object.cpp(57): error: no instance of function template "example<v>::operator() [with v='a']" matches the argument list
                argument types are: (receiver *, void (receiver::*)(char))
                object type is: example<'a'>
            obj_caller<example<'a'>, receiver, void (receiver::*)(char) > foo = sender (this, &receiver::callme);
                                                                                ^
    
    basic_object.cpp(60): error: no instance of function template "example<v>::operator() [with v='a']" matches the argument list
                argument types are: (receiver *, void (receiver::*)(char))
                object type is: example<'a'>
            sender(this, &receiver::callme).exec();
            ^
    
    basic_object.cpp(41): error: expression must have (pointer-to-) function type
                obj->*f(v);
                      ^
              detected during:
                instantiation of "void example<v>::do_call(ObjectT *, FunctionT *) [with v='a', ObjectT=receiver, FunctionT=void (receiver::*)(char)]" at line 30
                instantiation of "void obj_caller<T, ObjectT, FunctionT>::exec() [with T=example<'a'>, ObjectT=receiver, FunctionT=void (receiver::*)(char)]" 
    
    compilation aborted for basic_object.cpp (code 2)
    

    EDIT: Änderung des Methodenaufrufs in basic_object.cpp:41 .. thx to Bashar

    [ Dieser Beitrag wurde am 17.06.2003 um 10:08 Uhr von TheMummy editiert. ]



  • hm, pack das ganze mal in ne .cpp Datei, glaub nicht das C Templates kennt(oder die iostream ;)).

    nach #include <iostream> fehlt noch darunter ein using namespace std; (zumindest im MSVC; weis net wie das bei anderen Compilern ist.)

    Devil

    [ Dieser Beitrag wurde am 17.06.2003 um 10:04 Uhr von devil81 editiert. ]



  • devil81: du bist ja ein selten lustiges Forumsskript. Aber sag bitten deinem Schöpfer er soll auch testen ob in dem vorangegangenen Post Dateinamen die auf .cpp enden vorkommen.



  • hier ist eine andere Variante. Diesmal wird über den Paramtertyp der Funktion ausgeprägt:

    #include <iostream>
    template <class T, class ObjectT, class ParamT>
    struct obj_caller;
    
    template <class T>
    struct basic_object
    {
        inline T const& derived() const
                { return *static_cast<T const*>(this); }
    
        template <class ObjectT, class ParamT>
            inline obj_caller<T, ObjectT, ParamT> operator()(ObjectT *obj,void (ObjectT::*function)(ParamT)) const
            {
                return obj_caller<T, ObjectT, ParamT>(derived(), obj, function);
            }
    };
    
    template <class T, class ObjectT, class ParamT>
    struct obj_caller : public basic_object<obj_caller<T,ObjectT, ParamT> >
    {
        T caller;
        ObjectT *callee;
        void (ObjectT::*function)(ParamT);
    
        obj_caller(const T &m, ObjectT *c,void (ObjectT::*f)(ParamT) ) : caller(m), callee(c), function(f) {}
    
        void exec()
        {
            caller.do_call(callee,function);
        }
    
    };
    
    template <char v>
    struct example : public basic_object<example < v> >
    {
        template <class ObjectT, class ParamT>
            inline  void do_call(ObjectT *obj ,void (ObjectT::*function)(ParamT) )
            {
                obj->*function(v);
            }
    
    };
    
    struct receiver 
    {
        example<'a'> sender;
    
        void callme(char value) 
        {
            std::cout << "Got called with " << value << std::endl;
        }
    
        void run()
        {
            obj_caller<example<'a'>, receiver, char > foo = sender (this, &receiver::callme);
            foo.exec();
    
            sender(this, &receiver::callme).exec();
        }
    };
    
    int main()
    {
        receiver obj;
        obj.run();
        return 0;
    }
    
    basic_object2.cpp: In member function `void example<v>::do_call(ObjectT*, void 
       (ObjectT::*)(ParamT)) [with ObjectT = receiver, ParamT = char, char v = 
       'a']':
    basic_object2.cpp:30:   instantiated from `void obj_caller<T, ObjectT, ParamT>::exec() [with T = example<'a'>, ObjectT = receiver, ParamT = char]'
    basic_object2.cpp:58:   instantiated from here
    basic_object2.cpp:41: must use .* or ->* to call pointer-to-member function in 
       `function (...)'
    
    basic_object2.cpp(41): error: expression must have (pointer-to-) function type
                obj->*function(v);
                      ^
              detected during:
                instantiation of "void example<v>::do_call(ObjectT *, void (ObjectT::*)(ParamT)) [with v='a', ObjectT=receiver, ParamT=char]" at line 30
                instantiation of "void obj_caller<T, ObjectT, ParamT>::exec() [with T=example<'a'>, ObjectT=receiver, ParamT=char]" 
    
    compilation aborted for basic_object2.cpp (code 2)
    


  • Original erstellt von TheMummy:
    devil81: du bist ja ein selten lustiges Forumsskript. Aber sag bitten deinem Schöpfer er soll auch testen ob in dem vorangegangenen Post Dateinamen die auf .cpp enden vorkommen.

    hm, lustig. ich lach mich krank.
    Erstick doch an deinem Problem, und komischer weise wurde der Beitrag ja nach meinem
    Editiert...

    Devil



  • devil, wenn man keine ahnung hat, einfach mal den mund halten 🙂



  • zeile 41 sollte so aussehen: (obj->*function)(v);

    Bye Peter.



  • Danke Peter !
    basic_object2.cpp funktioniert. Damit könnte ich leben... Gibt es auch einen Weg basic_object.cpp compilierbar zu machen?



  • Oke das Problem wurde komplett gelöst, basic_object.cpp ist lauffähig sobald man den Funktionsparameter von FunctionT & f in FunctionT f umwandelt ...

    #include <iostream>
    template <class T, class ObjectT, class FunctionT>
    struct obj_caller;
    
    template <class T>
    struct basic_object
    {
        inline T const& derived() const
                { return *static_cast<T const*>(this); }
    
        template <class ObjectT, class FunctionT>
            inline obj_caller<T, ObjectT, FunctionT> operator()(ObjectT *obj, FunctionT v) const
            {
                return obj_caller<T, ObjectT, FunctionT>(derived(), obj, v);
            }
    };
    
    template <class T, class ObjectT, class FunctionT>
    struct obj_caller : public basic_object<obj_caller<T,ObjectT, FunctionT> >
    {
        T caller;
        ObjectT *callee;
        FunctionT function;   
    
        obj_caller(const T &m, ObjectT *c, FunctionT f) : caller(m), callee(c), function(f) {}
    
        void exec()
        {
            caller.do_call(callee,function);
        }
    
    };
    template <char v>
    struct example : public basic_object<example < v> >
    {
        template <class ObjectT, class FunctionT>
            inline  void do_call(ObjectT *obj, FunctionT f)
            {
                (obj->*f)(v);
            }
    
    };
    
    struct receiver 
    {
        example<'a'> sender;
    
        void callme(char value) 
        {
            std::cout << "Got called with " << value << std::endl;
        }
    
        void run()
        {
            obj_caller<example<'a'>, receiver, void (receiver::*)(char) > foo = sender(this, &receiver::callme);
            foo.exec();
    
            sender(this, &receiver::callme).exec();
        }
    };
    
    int main()
    {
        receiver obj;
        obj.run();
        return 0;
    }
    

    ... vielen Dank an MrN


Anmelden zum Antworten