Re: [sigc] Generic member functors



JinXXXX Kili Billl schrieb:
>> <code>
>> Parent p;
>> Child c;
>> 
>> sigc::slot<int, Parent*, int, double, char> myclosure;
>> 
>> myclosure = sigc::mem_fun(&Parent::f);
>> const int ret1 = myclosure(&p, 0, 1.0, 'c');
>> 
>> myclosure = sigc::mem_fun(&Child::g); <-- Error line
>> const int ret2 = myclosure(&c, 0, 1.0, 'c');
>> </code>
> 
> Does this code compile for you? I just did copy and paste and tried to
> compile the above code. The result was:
> 
> error: invalid conversion from ‘Parent* const’ to ‘Child*’

Sorry, my fault, I didn't try to compile it.


> So, if this is the right way to cope with my problem, why it refuses to
> compile?

Because in the end the slot must call the functor stored in the slot
(the functor that you assign to the slot).
The function slot4<int, Parent*, int double, char>::call_it() calls the
mem_functor3<int, Child*, int, double, char> with the parameter types
(int, Parent*, int, double, char) - Parent* is not convertible to Child*
or Child&.


You have 2 possibilities:

1) make g() [pure] virtual in Parent to get polymorphic runtime behaviour.
If you need to be totally flexible about the object instance during
runtime then this is the right solution.

2) Rather use mem_fun() to bind the object instance than specifying the
instance when calling the slot.
If you can decide already at compile time which object instance to use
then you can use this solution.


Here is some code to show what I mean:
1)
<code>
class Parent
{
public:
  int f(int, double, char)
  {
    return 0;
  }

  virtual int g(int, double, char) = 0;
};

class Child: public Parent
{
public:
  // virtuals from Parent
  virtual int g(int, double, char)
  {
    return 0;
  }
};

// somewhere else:
Parent p;
Child c1, c2;
sigc::slot<int, Parent*, int, double, char> myclosure;

myclosure = sigc::mem_fun(&Parent::f);
// call p->f()
myclosure(&p, 0, 1.0, 'c');

myclosure = sigc::mem_fun(&Parent::g);
// call c1->g()
myclosure(&c1, 0, 1.0, 'c');
// call c2->g()
myclosure(&c2, 0, 1.0, 'c');
</code>


2)
<code>
class Parent
{
public:
  int f(int, double, char)
  {
    return 0;
  }
};

class Child: public Parent
{
public:
  int g(int, double, char)
  {
    return 0;
  }
};


// somewhere else
Parent p;
Child c1, c2;
sigc::slot<int, int, double, char> myclosure;

// call p->f()
myclosure = sigc::mem_fun(&p, &Parent::f);
myclosure(0, 1.0, 'c');

// call c1->g()
myclosure = sigc::mem_fun(&c1, &Child::g);
myclosure(0, 1.0, 'c');

// call c2->g()
myclosure = sigc::mem_fun(&c2, &Child::g);
myclosure(0, 1.0, 'c');
</code>



Klaus


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]