Member and static functions while assignment

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

    Member and static functions while assignment

    I have the following problem.

    class Base
    {
    public:
    void (*pfunc) (int) = 0;
    };

    class Derived : public Base
    {
    public:
    void (*pfunc) (int a)
    {
    // Stuff
    }
    };


    class Foo
    {
    private:
    void (*pf) (int);
    public:
    Foo (Base* ptr)
    {
    pf = ptr->pfunc; // Error, because pfunc is a member function,
    not static
    }
    };

    Is there any way to do something like "pf = ptr->pfunc"?


    Alex Vinokur
    email: alex DOT vinokur AT gmail DOT com



  • mlimber

    #2
    Re: Member and static functions while assignment

    Alex Vinokur wrote:[color=blue]
    > I have the following problem.
    >
    > class Base
    > {
    > public:
    > void (*pfunc) (int) = 0;[/color]

    This line won't compile. It's neither a static integral constant nor a
    pure virtual function, but you seem to have mixed the syntax for the
    two.
    [color=blue]
    > };
    >
    > class Derived : public Base
    > {
    > public:
    > void (*pfunc) (int a)[/color]

    You can't define a body for a pointer to a function. Please see the FAQ
    for this group on how to post code:


    [color=blue]
    > {
    > // Stuff
    > }
    > };
    >
    >
    > class Foo
    > {
    > private:
    > void (*pf) (int);
    > public:
    > Foo (Base* ptr)
    > {
    > pf = ptr->pfunc; // Error, because pfunc is a member function,
    > not static[/color]

    You have a lot bigger problems than that!
    [color=blue]
    > }
    > };
    >
    > Is there any way to do something like "pf = ptr->pfunc"?[/color]

    Yes. See the FAQs:



    Cheers! --M

    Comment

    • Victor Bazarov

      #3
      Re: Member and static functions while assignment

      Alex Vinokur wrote:[color=blue]
      > I have the following problem.
      >
      > class Base
      > {
      > public:
      > void (*pfunc) (int) = 0;[/color]

      A pointer to a function taking an int and returning void.
      [color=blue]
      > };
      >
      > class Derived : public Base
      > {
      > public:
      > void (*pfunc) (int a)[/color]

      Huh? Another pointer to a function...
      [color=blue]
      > {
      > // Stuff[/color]

      Are you trying to define a body after declaring a pointer to a function?
      [color=blue]
      > }
      > };
      >
      >
      > class Foo
      > {
      > private:
      > void (*pf) (int);[/color]

      OK, a pointer to a function.
      [color=blue]
      > public:
      > Foo (Base* ptr)
      > {
      > pf = ptr->pfunc; // Error, because pfunc is a member function,
      > not static
      > }
      > };
      >
      > Is there any way to do something like "pf = ptr->pfunc"?[/color]

      What are you trying to accomplish here? Perhaps read about the template
      'std::binder_1s t', you can do something like

      pf = std::bind1st(&B ase::pfunc, ptr);

      although it is a bit convoluted, but should get you what you want, IIUYC.

      Next time try to show what you intend to do with 'pf'.

      V

      Comment

      • Alex Vinokur

        #4
        Re: Member and static functions while assignment


        "mlimber" <mlimber@gmail. com> wrote in message
        news:1129727774 .558775.269250@ o13g2000cwo.goo glegroups.com.. .[color=blue]
        > Alex Vinokur wrote:[color=green]
        > > I have the following problem.
        > >
        > > class Base
        > > {
        > > public:
        > > void (*pfunc) (int) = 0;[/color]
        >
        > This line won't compile. It's neither a static integral constant nor a
        > pure virtual function, but you seem to have mixed the syntax for the
        > two.[/color]
        [snip]

        My first message was unlucky. Please ignore it.

        Here is problematic program.
        ====== foo1.cpp ======
        struct Base
        {
        virtual void func (int) = 0;
        };

        struct Derived : public Base
        {
        void func (int)
        {
        // Stuff
        }
        };

        struct Foo
        {
        void (*pfunc) (int);
        Base* p_;

        Foo (Base* p) : p_ (p) {}

        void doit ()
        {

        // Here is what I want to reach
        pfunc = p_->func;

        // ------------------------
        // g++ 4.0.1 produces the following error message:
        // ............... .........
        // error: argument of type 'void (Base::)(int)'
        // does not match 'void (*)(int)
        // ............... .........
        // because func() is _member_ (not static) function
        // ------------------------
        }
        };


        int main ()
        {
        Base* p = new Derived;
        Foo foo (p);
        delete p;

        return 0;
        }
        =============== =======


        Here is a _partial_ solution of the problem.
        ====== foo2.cpp ======
        struct Base
        {
        virtual void func (int) = 0;
        };

        struct Derived : public Base
        {
        void func (int)
        {
        // Stuff
        }
        };

        struct Foo
        {
        void (*pfunc) (int);
        static Base* p_s;

        Foo (Base* p) { p_s = p; }

        static void wrapper(int a)
        {
        p_s->func (a);
        }

        void doit ()
        {
        pfunc = wrapper;
        }
        };
        Base* Foo::p_s = 0;


        int main ()
        {
        Base* p = new Derived;
        Foo foo (p);
        delete p;

        return 0;
        }

        =============== =======


        --
        Alex Vinokur
        email: alex DOT vinokur AT gmail DOT com



        Comment

        • Victor Bazarov

          #5
          Re: Member and static functions while assignment

          Alex Vinokur wrote:[color=blue]
          > "mlimber" <mlimber@gmail. com> wrote in message
          > news:1129727774 .558775.269250@ o13g2000cwo.goo glegroups.com.. .
          >[color=green]
          >>Alex Vinokur wrote:
          >>[color=darkred]
          >>>I have the following problem.
          >>>
          >>>class Base
          >>>{
          >>> public:
          >>> void (*pfunc) (int) = 0;[/color]
          >>
          >>This line won't compile. It's neither a static integral constant nor a
          >>pure virtual function, but you seem to have mixed the syntax for the
          >>two.[/color]
          >
          > [snip]
          >
          > My first message was unlucky. Please ignore it.
          >
          > Here is problematic program.
          > ====== foo1.cpp ======
          > struct Base
          > {
          > virtual void func (int) = 0;[/color]

          Add:

          virtual ~Base() {}
          [color=blue]
          > };
          >
          > struct Derived : public Base
          > {
          > void func (int)
          > {
          > // Stuff
          > }
          > };
          >
          > struct Foo
          > {
          > void (*pfunc) (int);
          > Base* p_;
          >
          > Foo (Base* p) : p_ (p) {}
          >
          > void doit ()
          > {
          >
          > // Here is what I want to reach
          > pfunc = p_->func;[/color]

          And then what? How do you intend to use 'pfunc'?
          [color=blue]
          >
          > // ------------------------
          > // g++ 4.0.1 produces the following error message:
          > // ............... .........
          > // error: argument of type 'void (Base::)(int)'
          > // does not match 'void (*)(int)
          > // ............... .........
          > // because func() is _member_ (not static) function
          > // ------------------------
          > }
          > };
          >
          >
          > int main ()
          > {
          > Base* p = new Derived;
          > Foo foo (p);
          > delete p;
          >
          > return 0;
          > }
          > =============== =======
          >
          >
          > Here is a _partial_ solution of the problem.[/color]

          Which problem?
          [color=blue]
          > ====== foo2.cpp ======
          > struct Base
          > {
          > virtual void func (int) = 0;
          > };
          >
          > struct Derived : public Base
          > {
          > void func (int)
          > {
          > // Stuff
          > }
          > };
          >
          > struct Foo
          > {
          > void (*pfunc) (int);
          > static Base* p_s;
          >
          > Foo (Base* p) { p_s = p; }
          >
          > static void wrapper(int a)
          > {
          > p_s->func (a);
          > }
          >
          > void doit ()
          > {
          > pfunc = wrapper;
          > }
          > };
          > Base* Foo::p_s = 0;
          >
          >
          > int main ()
          > {
          > Base* p = new Derived;
          > Foo foo (p);
          > delete p;
          >
          > return 0;
          > }
          >
          > =============== =======[/color]

          Study this:

          ////////////////////////////////////
          struct Base
          {
          virtual void func (int) = 0;
          virtual ~Base() {}
          };

          struct Derived : public Base
          {
          void func(int)
          {
          // Stuff
          }
          };

          struct Foo
          {
          void (Base::*pfunc) (int);

          Foo (void (Base::*pf) (int)) : pfunc(pf) {}

          void doit(Base* p_)
          {
          (p_->*pfunc)(42);
          }
          };


          int main ()
          {
          Base* p = new Derived;
          Foo foo(&Base::func );

          foo.doit(p);

          delete p;
          }
          /////////////////////////////////////////

          V

          Comment

          • mlimber

            #6
            Re: Member and static functions while assignment

            Alex Vinokur wrote:[color=blue]
            > My first message was unlucky. Please ignore it.
            >
            > Here is problematic program.
            > ====== foo1.cpp ======
            > struct Base
            > {
            > virtual void func (int) = 0;
            > };
            >
            > struct Derived : public Base
            > {
            > void func (int)
            > {
            > // Stuff
            > }
            > };
            >
            > struct Foo
            > {
            > void (*pfunc) (int);
            > Base* p_;
            >
            > Foo (Base* p) : p_ (p) {}
            >
            > void doit ()
            > {
            >
            > // Here is what I want to reach
            > pfunc = p_->func;
            >
            > // ------------------------
            > // g++ 4.0.1 produces the following error message:
            > // ............... .........
            > // error: argument of type 'void (Base::)(int)'
            > // does not match 'void (*)(int)
            > // ............... .........
            > // because func() is _member_ (not static) function
            > // ------------------------
            > }
            > };
            >[/color]

            Ok, now you've posed the problem correctly, and in order to find the
            solution, all you need to do is read the FAQs to which I previously
            referred you:



            [snip][color=blue]
            > Here is a _partial_ solution of the problem.
            > ====== foo2.cpp ======
            > struct Base
            > {
            > virtual void func (int) = 0;
            > };
            >
            > struct Derived : public Base
            > {
            > void func (int)
            > {
            > // Stuff
            > }
            > };
            >
            > struct Foo
            > {
            > void (*pfunc) (int);
            > static Base* p_s;
            >
            > Foo (Base* p) { p_s = p; }
            >
            > static void wrapper(int a)
            > {
            > p_s->func (a);
            > }
            >
            > void doit ()
            > {
            > pfunc = wrapper;
            > }
            > };
            > Base* Foo::p_s = 0;
            >
            >
            > int main ()
            > {
            > Base* p = new Derived;
            > Foo foo (p);
            > delete p;
            >
            > return 0;
            > }[/color]

            This is not a good solution. It is not necessary to resort to static
            members and methods. See the FAQs.

            Cheers! --M

            Comment

            • Alex Vinokur

              #7
              Re: Member and static functions while assignment


              Victor Bazarov wrote:
              [snip][color=blue]
              > Study this:
              >
              > ////////////////////////////////////
              > struct Base
              > {
              > virtual void func (int) = 0;
              > virtual ~Base() {}
              > };
              >
              > struct Derived : public Base
              > {
              > void func(int)
              > {
              > // Stuff
              > }
              > };
              >
              > struct Foo
              > {[/color]
              ---------------------------------[color=blue]
              > void (Base::*pfunc) (int);[/color]
              But here I have to use
              void (*pfunc) (int);
              ---------------------------------[color=blue]
              >
              > Foo (void (Base::*pf) (int)) : pfunc(pf) {}
              >
              > void doit(Base* p_)
              > {
              > (p_->*pfunc)(42);
              > }
              > };
              >
              >
              > int main ()
              > {
              > Base* p = new Derived;
              > Foo foo(&Base::func );
              >
              > foo.doit(p);
              >
              > delete p;
              > }
              > /////////////////////////////////////////
              >
              > V[/color]


              Alex Vinokur

              Comment

              • Alf P. Steinbach

                #8
                Re: Member and static functions while assignment

                * Alex Vinokur:[color=blue]
                >
                > I have to use
                > void (*pfunc) (int);
                >
                > [to call a member function][/color]

                If you have any leeway at all, consider using a functor object instead. That
                can encapsulate an ordinary static function, or a member function bound to an
                object (sometimes called a _closure_ or a _delegate_), or whatever. See the
                FAQ items at the end of the FAQ page that "mlimber" pointed to.

                --
                A: Because it messes up the order in which people normally read text.
                Q: Why is it such a bad thing?
                A: Top-posting.
                Q: What is the most annoying thing on usenet and in e-mail?

                Comment

                • Alex Vinokur

                  #9
                  Re: Member and static functions while assignment


                  Alf P. Steinbach wrote:[color=blue]
                  > * Alex Vinokur:[color=green]
                  > >
                  > > I have to use
                  > > void (*pfunc) (int);
                  > >
                  > > [to call a member function][/color]
                  >
                  > If you have any leeway at all, consider using a functor object instead. That
                  > can encapsulate an ordinary static function, or a member function bound to an
                  > object (sometimes called a _closure_ or a _delegate_), or whatever. See the
                  > FAQ items at the end of the FAQ page that "mlimber" pointed to.
                  >[/color]
                  [snip]

                  Thanks.

                  I saw the FAQ.

                  But it seems that it doesn't solve my problem.


                  Here my situation.

                  struct BaseBar
                  {
                  // Stuff: Data members
                  virtual void callback (int) = 0;
                  virtual ~BaseBar() {}
                  };

                  struct Bar1 : public BaseBar
                  {
                  // Stuff: Data members
                  void callback (int)
                  {
                  // Stuff
                  }
                  };


                  struct Bar2 : public BaseBar
                  {
                  // Stuff: Data members
                  void callback (int)
                  {
                  // Stuff
                  }
                  };

                  struct Config
                  {
                  // Stuff: Data members
                  void (*the_callback) (int); // We can't change this prototype

                  };

                  struct Foo
                  {
                  // Stuff: Data members
                  Config config_;
                  Foo (BaseBar* ptr_i)
                  {
                  // Stuff
                  // Here I have to do what is impossible to do:
                  // -----------------------
                  // config_.the_cal lback = ptr_i->callback;
                  // -----------------------
                  }
                  };

                  int main ()
                  {
                  Bar1 bar1;
                  Bar2 bar2;

                  Foo foo1 (&bar1);
                  Foo foo2 (&bar2);
                  Foo foo3 (&bar1);

                  return 0;
                  }


                  The approach from

                  doesn't help here because we have several Bar-ojects created.


                  Alex Vinokur

                  Comment

                  • Alf P. Steinbach

                    #10
                    Re: Member and static functions while assignment

                    * Alex Vinokur:[color=blue]
                    > void (*the_callback) (int); // We can't change this prototype
                    >
                    >
                    > The approach from
                    > http://www.parashift.com/c++-faq-lit....html#faq-33.2
                    > doesn't help here because we have several Bar-ojects created.[/color]

                    If the callback is only called during initialization I don't see why not.

                    Otherwise, if you can specify the int argument to the callback, then use a
                    std::map as the global, not just a single pointer, and the int argument as key
                    to the map.

                    Otherwise, if you can't specify the argument then it seems the API you're
                    using supports only a single callback which can be called at any time, and you
                    then have to decide whether you want just a single object to receive the call
                    or whether to distribute it to all objects, or what.

                    --
                    A: Because it messes up the order in which people normally read text.
                    Q: Why is it such a bad thing?
                    A: Top-posting.
                    Q: What is the most annoying thing on usenet and in e-mail?

                    Comment

                    • Alex Vinokur

                      #11
                      Re: Member and static functions while assignment


                      Alf P. Steinbach wrote:[color=blue]
                      > * Alex Vinokur:[color=green]
                      > > void (*the_callback) (int); // We can't change this prototype
                      > >
                      > >
                      > > The approach from
                      > > http://www.parashift.com/c++-faq-lit....html#faq-33.2
                      > > doesn't help here because we have several Bar-ojects created.[/color]
                      >
                      > If the callback is only called during initialization I don't see why not.
                      >
                      > Otherwise, if you can specify the int argument to the callback, then use a
                      > std::map as the global, not just a single pointer, and the int argument as key
                      > to the map.[/color]


                      I tried to do something like this.

                      struct BaseBar
                      {
                      // Stuff: Data members
                      virtual void callback (int) = 0;
                      virtual ~BaseBar() {}
                      };


                      struct Bar1 : public BaseBar
                      {
                      // Stuff: Data members
                      void callback (int)
                      {
                      // Stuff
                      }
                      };


                      struct Bar2 : public BaseBar
                      {
                      // Stuff: Data members
                      void callback (int)
                      {
                      // Stuff
                      }
                      };


                      struct Config
                      {
                      // Stuff: Data members
                      void (*the_callback) (int); // We can't change this prototype
                      };


                      struct Foo
                      {
                      static int id_counter_s;
                      static map<int, BaseBar*> p_bar_s;
                      const int id_;

                      Config config_;

                      static foo_callback (int x)
                      {
                      p_bar_s[id_ /* id_ is member; so it is illegal */]->callback (x);

                      }

                      Foo (BaseBar* ptr_i) : id_ (id_counter_s)
                      {
                      p_bar_s[id_] = ptr_i;

                      // Stuff
                      config_.the_cal lback = foo_callback;
                      }
                      };
                      int Foo::id_counter _s = 0;
                      map<int, BaseBar*> Foo::p_bar_s;


                      int main ()
                      {
                      Bar1 bar1;
                      Bar2 bar2;

                      Foo foo1 (&bar1);
                      Foo foo2 (&bar2);
                      Foo foo3 (&bar1);


                      return 0;



                      }

                      [color=blue]
                      >
                      > Otherwise, if you can't specify the argument then it seems the API you're
                      > using supports only a single callback which can be called at any time, and you
                      > then have to decide whether you want just a single object to receive the call
                      > or whether to distribute it to all objects, or what.
                      >[/color]


                      Alex Vinokur
                      email: alex DOT vinokur AT gmail DOT com



                      Comment

                      • Alex Vinokur

                        #12
                        Re: Member and static functions while assignment


                        "Alex Vinokur" <alexvn@users.s ourceforge.net> wrote in message news:1130064910 .871572.251600@ g47g2000cwa.goo glegroups.com.. .[color=blue]
                        >
                        > Alf P. Steinbach wrote:[color=green]
                        > > * Alex Vinokur:[color=darkred]
                        > > > void (*the_callback) (int); // We can't change this prototype
                        > > >
                        > > >
                        > > > The approach from
                        > > > http://www.parashift.com/c++-faq-lit....html#faq-33.2
                        > > > doesn't help here because we have several Bar-ojects created.[/color]
                        > >
                        > > If the callback is only called during initialization I don't see why not.
                        > >
                        > > Otherwise, if you can specify the int argument to the callback, then use a
                        > > std::map as the global, not just a single pointer, and the int argument as key
                        > > to the map.[/color]
                        >
                        >
                        > I tried to do something like this.[/color]
                        [snip][color=blue][color=green]
                        > >
                        > > Otherwise, if you can't specify the argument then it seems the API you're
                        > > using supports only a single callback which can be called at any time, and you
                        > > then have to decide whether you want just a single object to receive the call
                        > > or whether to distribute it to all objects, or what.
                        > >[/color][/color]
                        [snip]

                        I have resolved the problem in my _specific_ conditions.

                        Here is an erroneous program that doesn't take into account any _specific_ conditions.

                        ------ erroneous program ------
                        struct BaseCaller
                        {
                        virtual void callback (long) = 0;
                        virtual ~BaseCaller() {}
                        };


                        struct Caller1 : public BaseCaller
                        {
                        void callback (long)
                        {
                        // Stuff
                        }
                        };


                        struct Caller2 : public BaseCaller
                        {
                        void callback (long)
                        {
                        // Stuff
                        }
                        };


                        struct Worker
                        {
                        void (*the_callback) (long); // We can't change this prototype
                        };


                        #define RED 1
                        #define BLUE 2
                        #define GREEN 3

                        struct Called
                        {
                        const int type_; // RED, BLUE or GREEN
                        Worker Worker_;
                        Called (int type_i, BaseCaller* ptr_i) : type_ (type_i)
                        {
                        Worker_.the_cal lback = ptr_i->callback; // Erroneous
                        }
                        };


                        int main ()
                        {
                        Caller1 caller1;
                        Caller2 caller2;

                        Called called1 (RED, &caller1);
                        Called called2 (BLUE, &caller2);
                        Called called3 (GREEN, &caller1);

                        return 0;
                        }
                        -------------------------------


                        Here are _specific_ conditions:
                        1. Maximum three types of Called-object can exist simultaneously.
                        2. No type of Called-object (RED, BLUE, GREEN) can exist more than once.

                        Here is a valid program.
                        ------ valid program ------

                        #include <cassert>
                        #include <map>
                        using namespace std;

                        struct BaseCaller
                        {
                        virtual void callback (long) = 0;
                        virtual ~BaseCaller() {}
                        };


                        struct Caller1 : public BaseCaller
                        {
                        void callback (long)
                        {
                        // Stuff
                        }
                        };


                        struct Caller2 : public BaseCaller
                        {
                        void callback (long)
                        {
                        // Stuff
                        }
                        };


                        struct Worker
                        {
                        void (*the_callback) (long); // We can't change this prototype
                        };


                        #define RED 1
                        #define BLUE 2
                        #define GREEN 3

                        struct Called
                        {
                        static map<int, BaseCaller*> types_s;
                        const int type_; // RED, BLUE or GREEN
                        Worker Worker_;

                        static void red_callback_s (long arg_i)
                        {
                        types_s[RED]->callback(arg_i );
                        }

                        static void blue_callback_s (long arg_i)
                        {
                        types_s[BLUE]->callback(arg_i );
                        }

                        static void green_callback_ s (long arg_i)
                        {
                        types_s[GREEN]->callback(arg_i );
                        }

                        Called (int type_i, BaseCaller* ptr_i) : type_ (type_i)
                        {
                        assert (types_s.count( type_) == 0); // In actual program to be replaced by some check
                        types_s[type_] = ptr_i;

                        switch (type_)
                        {
                        case RED:
                        Worker_.the_cal lback = red_callback_s;
                        break;

                        case BLUE:
                        Worker_.the_cal lback = blue_callback_s ;
                        break;

                        case GREEN:
                        Worker_.the_cal lback = green_callback_ s;
                        break;

                        default:
                        assert(0);
                        break;
                        }

                        }

                        };
                        map<int, BaseCaller*> Called::types_s ;


                        int main ()
                        {
                        Caller1 caller1;
                        Caller2 caller2;

                        Called called1 (RED, &caller1);
                        Called called2 (BLUE, &caller2);
                        Called called3 (GREEN, &caller1);

                        return 0;
                        }
                        ---------------------------


                        --
                        Alex Vinokur
                        email: alex DOT vinokur AT gmail DOT com





                        Comment

                        • Alex Vinokur

                          #13
                          Re: Member and static functions while assignment


                          Alex Vinokur wrote:

                          [snip]
                          [color=blue]
                          > Here is a valid program.
                          > ------ valid program ------[/color]

                          [snip]
                          [color=blue]
                          > struct Called
                          > {[/color]
                          [snip][color=blue]
                          >
                          > Called (int type_i, BaseCaller* ptr_i) : type_ (type_i)
                          > {
                          > assert (types_s.count( type_) == 0); // In actual program to be replaced by some check
                          > types_s[type_] = ptr_i;
                          >
                          > switch (type_)
                          > {
                          > case RED:
                          > Worker_.the_cal lback = red_callback_s;
                          > break;
                          >
                          > case BLUE:
                          > Worker_.the_cal lback = blue_callback_s ;
                          > break;
                          >
                          > case GREEN:
                          > Worker_.the_cal lback = green_callback_ s;
                          > break;
                          >
                          > default:
                          > assert(0);
                          > break;
                          > }
                          > }[/color]

                          ~Called
                          {
                          types_s.erase(t ype_);
                          }[color=blue]
                          >
                          >
                          > };[/color]
                          [snip]

                          Alex Vinokur
                          email: alex DOT vinokur AT gmail DOT com



                          Comment

                          • Aleksey Loginov

                            #14
                            Re: Member and static functions while assignment


                            Alex Vinokur wrote:[color=blue]
                            > "Alex Vinokur" <alexvn@users.s ourceforge.net> wrote in message news:1130064910 .871572.251600@ g47g2000cwa.goo glegroups.com.. .
                            >
                            > Here are _specific_ conditions:
                            > 1. Maximum three types of Called-object can exist simultaneously.
                            > 2. No type of Called-object (RED, BLUE, GREEN) can exist more than once.
                            >
                            > Here is a valid program.
                            > ------ valid program ------
                            >
                            > #include <cassert>
                            > #include <map>
                            > using namespace std;
                            >
                            > struct BaseCaller
                            > {
                            > virtual void callback (long) = 0;
                            > virtual ~BaseCaller() {}
                            > };
                            >
                            >
                            > struct Caller1 : public BaseCaller
                            > {
                            > void callback (long)
                            > {
                            > // Stuff
                            > }
                            > };
                            >
                            >
                            > struct Caller2 : public BaseCaller
                            > {
                            > void callback (long)
                            > {
                            > // Stuff
                            > }
                            > };
                            >
                            >
                            > struct Worker
                            > {
                            > void (*the_callback) (long); // We can't change this prototype
                            > };
                            >
                            >
                            > #define RED 1
                            > #define BLUE 2
                            > #define GREEN 3
                            >
                            > struct Called
                            > {
                            > static map<int, BaseCaller*> types_s;
                            > const int type_; // RED, BLUE or GREEN
                            > Worker Worker_;
                            >
                            > static void red_callback_s (long arg_i)
                            > {
                            > types_s[RED]->callback(arg_i );
                            > }
                            >
                            > static void blue_callback_s (long arg_i)
                            > {
                            > types_s[BLUE]->callback(arg_i );
                            > }
                            >
                            > static void green_callback_ s (long arg_i)
                            > {
                            > types_s[GREEN]->callback(arg_i );
                            > }
                            >
                            > Called (int type_i, BaseCaller* ptr_i) : type_ (type_i)
                            > {
                            > assert (types_s.count( type_) == 0); // In actual program to be replaced by some check
                            > types_s[type_] = ptr_i;
                            >
                            > switch (type_)
                            > {
                            > case RED:
                            > Worker_.the_cal lback = red_callback_s;
                            > break;
                            >
                            > case BLUE:
                            > Worker_.the_cal lback = blue_callback_s ;
                            > break;
                            >
                            > case GREEN:
                            > Worker_.the_cal lback = green_callback_ s;
                            > break;
                            >
                            > default:
                            > assert(0);
                            > break;
                            > }
                            >
                            > }
                            >
                            > };
                            > map<int, BaseCaller*> Called::types_s ;
                            >
                            >
                            > int main ()
                            > {
                            > Caller1 caller1;
                            > Caller2 caller2;
                            >
                            > Called called1 (RED, &caller1);
                            > Called called2 (BLUE, &caller2);
                            > Called called3 (GREEN, &caller1);
                            >
                            > return 0;
                            > }
                            > ---------------------------
                            >[/color]


                            #include <algorithm>
                            #include <iostream>

                            struct BaseCaller
                            {
                            virtual void callback (long) = 0;
                            virtual ~BaseCaller() {}
                            };


                            struct Caller1 : public BaseCaller
                            {
                            void callback (long)
                            {
                            // Stuff
                            }
                            };


                            struct Caller2 : public BaseCaller
                            {
                            void callback (long)
                            {
                            // Stuff
                            }
                            };


                            struct Worker
                            {
                            void (*the_callback) (long); // We can't change this prototype
                            };

                            enum types { red, blue, green };

                            template<types id>
                            struct CallerWrapper
                            {
                            CallerWrapper ( BaseCaller * ptr_i ) {
                            CallerWrapper<i d>::instance (ptr_i); }

                            static BaseCaller * instance ( BaseCaller * ptr_i ) {
                            static BaseCaller * ptr_s = 0;

                            BaseCaller * tmp = ptr_s; ptr_s = ptr_i;
                            return tmp;
                            }

                            static BaseCaller * instance ( ) {
                            BaseCaller * tmp = CallerWrapper<i d>::instance (0);
                            CallerWrapper<i d>::instance (tmp);
                            return tmp;
                            }

                            static const types type = id;
                            static void callback ( long arg_i ) {
                            CallerWrapper<i d>::instance ()->callback (arg_i); }

                            };

                            struct Called
                            {
                            const types type_; // RED, BLUE or GREEN
                            Worker Worker_;

                            template< typename Singleton >
                            Called ( Singleton const & ) : type_ (Singleton::typ e) {
                            Worker_.the_cal lback = Singleton::call back; }

                            };


                            int main ()
                            {
                            Caller1 caller1;
                            Caller2 caller2;


                            Called called1 (CallerWrapper< red>(&caller1)) ;
                            Called called2 (CallerWrapper< blue>(&caller2) );
                            Called called3 (CallerWrapper< green>(&caller1 ));


                            return 0;

                            }

                            Comment

                            Working...