Pointer to member function - type

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jrx

    #1

    Pointer to member function - type

    I've got my_error exception type, defined as:

    class my_error : public std::runtime_er ror {
    public:
    my_error(const std::string& msg) : std::runtime_er ror(msg) {}
    };

    Then, I've got Wrapper class, that wraps my classes. I create it:

    Wrapper<my_erro rmy_error_wrapp er;
    my_error_wrappe r.addMethod(&my _error::what);

    The template method addMethod looks like:

    template <class T>
    class Wrapper {
    public:
    [...]
    template <class Result>
    void addMethod(Resul t (T::*method)()) {
    }
    };

    The problem is, that.. it doesn't work. It appears that, my_error::what
    has the type
    const char* (std::runtime_e rror::*)() const
    not:
    const char* (my_error::*)() const

    Quite tricky, because std::runtime_er ror also derives what() from
    std::exception.

    Is there any way to give pointer to such method as an argument?
    Except form:

    template <class Result, class Base>
    void addMethod(Resul t (Base::*method) ()) {
    STATIC_ASSERT(i s_derived<Base, T>::value);
    }

    Another question:
    Is it possible to obtain method type in some way like:
    template <class Method>
    void addMethod(Metho d m_ptr) {
    }

    I know there is something like "function type" used e.g. in
    boost::signals to write:
    boost::signal<v oid (const char*)my_signal ;
    Is there something like that for methods?

    thanks in advance ;)

    JRX
    --
    JRX --dev \dot jrx \at gmail \dot com
    If the words "open source" get you more excited than
    the words "free porn"...you might be a Game Developer.
    Registered Linux user# 383163
  • kwikius

    #2
    Re: Pointer to member function - type

    jrx wrote:
    The problem is, that.. it doesn't work. It appears that, my_error::what
    has the type
    const char* (std::runtime_e rror::*)() const
    not:
    const char* (my_error::*)() const
    >
    Quite tricky, because std::runtime_er ror also derives what() from
    std::exception.
    >
    Is there any way to give pointer to such method as an argument?
    In the above I think you need to make the signature const e.g:

    template <class T>
    class Wrapper {
    /*...*/
    //############### ############### #############
    void addMethod(Resul t (T::*method)() const) {
    //############### ############### ##############
    }
    };

    Unfortunately the error message is misleading. Try the above and the
    function should be found in the base class.


    To call it I think boost::function etc won't help. You could define
    your own functor maybe like this:

    #include <stdexcept>
    #include <iostream>


    template <typename Class>
    struct what_functor{
    Class* m_p_class;
    const char* (Class::* m_pf)()const;
    what_functor(Cl ass * p_class_in, const char* (Class::*
    pf_in)()const)
    : m_p_class(p_cla ss_in),m_pf(pf_ in){}

    const char* operator()()
    {
    return ( m_p_class->*(m_pf))();
    }
    };

    class my_error : public std::runtime_er ror {
    public:
    my_error(const std::string& msg) : std::runtime_er ror(msg) {}

    };


    int main()
    {
    my_error e("something" );
    // need a class instance pointer and the member function pointer
    // to init the functor
    what_functor<my _errorfunc(&e,& my_error::what) ;

    std::cout << func() <<'\n';
    }

    regards
    Andy Little

    Comment

    • jrx

      #3
      Re: Pointer to member function - type

      kwikius wrote:
      >
      In the above I think you need to make the signature const e.g:
      >
      template <class T>
      class Wrapper {
      /*...*/
      //############### ############### #############
      void addMethod(Resul t (T::*method)() const) {
      //############### ############### ##############
      }
      };
      >
      Unfortunately the error message is misleading. Try the above and the
      function should be found in the base class.
      Unfortunately it doesn't work either.
      Such signature:

      template <class Return>
      void addMethod(Retur n (T::*method)()c onst ) {
      }

      Causes error:
      error: no matching function for call to
      ‘Wrapper<my_e rror>::addMetho d(const char*std::runti me_error::*)()c onst)’

      >
      >
      To call it I think boost::function etc won't help. You could define
      your own functor maybe like this:
      >
      #include <stdexcept>
      #include <iostream>
      >
      >
      template <typename Class>
      struct what_functor{
      Class* m_p_class;
      const char* (Class::* m_pf)()const;
      what_functor(Cl ass * p_class_in, const char* (Class::*
      pf_in)()const)
      : m_p_class(p_cla ss_in),m_pf(pf_ in){}
      >
      const char* operator()()
      {
      return ( m_p_class->*(m_pf))();
      }
      };
      >
      class my_error : public std::runtime_er ror {
      public:
      my_error(const std::string& msg) : std::runtime_er ror(msg) {}
      >
      };
      >
      >
      int main()
      {
      my_error e("something" );
      // need a class instance pointer and the member function pointer
      // to init the functor
      what_functor<my _errorfunc(&e,& my_error::what) ;
      >
      std::cout << func() <<'\n';
      }
      >
      I know, it works, but why in my example it doesn't compile properly?


      --
      JRX --dev \dot jrx \at gmail \dot com
      If the words "open source" get you more excited than
      the words "free porn"...you might be a Game Developer.
      Registered Linux user# 383163

      Comment

      • kwikius

        #4
        Re: Pointer to member function - type

        jrx wrote:
        I know, it works, but why in my example it doesn't compile properly?
        It may be because your version has more template parameters and it
        can't make asumptions therefore.. maybe someone will give a better
        explanation. The following seems to give a similar message on gcc if
        the DERIVED_OVERRID E define is commented out. So you could try
        overriding the what function in your derived class. Note also the
        throw() part of the signature which seems to be required here.

        #include <stdexcept>
        #include <iostream>

        //comment out the define causes fail
        #define DERIVED_OVERRID E
        struct what_functor{
        template <typename Class, typename R>
        R operator()(Clas s * p_class, R (Class::* pf)()const)cons t
        {
        return ( p_class->*pf)();
        }
        };

        class my_error : public std::runtime_er ror {
        public:
        my_error(const std::string& msg) : std::runtime_er ror(msg) {}
        #ifdef DERIVED_OVERRID E
        const char * what() const throw()
        {
        return std::runtime_er ror::what();
        }
        #endif
        };

        int main()
        {
        my_error e("something" );
        what_functor func;

        std::cout << func(&e,&my_err or::what) <<'\n';
        }

        regards
        Andy Little

        Comment

        • jrx

          #5
          Re: Pointer to member function - type

          kwikius wrote:
          It may be because your version has more template parameters and it
          can't make asumptions therefore.. maybe someone will give a better
          explanation. The following seems to give a similar message on gcc if
          the DERIVED_OVERRID E define is commented out. So you could try
          overriding the what function in your derived class. Note also the
          throw() part of the signature which seems to be required here.
          >
          #include <stdexcept>
          #include <iostream>
          >
          //comment out the define causes fail
          #define DERIVED_OVERRID E
          struct what_functor{
          template <typename Class, typename R>
          R operator()(Clas s * p_class, R (Class::* pf)()const)cons t
          {
          return ( p_class->*pf)();
          }
          };
          >
          class my_error : public std::runtime_er ror {
          public:
          my_error(const std::string& msg) : std::runtime_er ror(msg) {}
          #ifdef DERIVED_OVERRID Esame case as in my code. But I think it should compile even if method what() isn't overridden.
          const char * what() const throw()
          {
          return std::runtime_er ror::what();
          }
          #endif
          };
          >
          int main()
          {
          my_error e("something" );
          what_functor func;
          >
          std::cout << func(&e,&my_err or::what) <<'\n';
          }
          That's the same case as in my code. But I think it should compile even
          1if method what() isn't overridden. I have no idea, why me_error::what
          behaves in such a strange way. Any suggestions for generic addMethod
          method declaration?

          --
          JRX --dev \dot jrx \at gmail \dot com
          If the words "open source" get you more excited than
          the words "free porn"...you might be a Game Developer.
          Registered Linux user# 383163

          Comment

          Working...