Topic: function ptr conversion


Author: gyro@netcom.com (Scott L. Burson)
Date: Sun, 5 Sep 1993 06:35:45 GMT
Raw View
In article <hopps.747078470@mmm.com> kjhopps@mmm.com writes:
>I have the following two classes, with the relevant portions shown.
>
>    class Base { public:
> typedef void (*BaseVoidFunc)(Base& b);
> void Apply(BaseVoidFunc func) { func(*this); }
>    };
>
>    template <class T> class Derived : public Base { public:
> typedef void (*DerivedVoidFunc)(Derived<T>& d);
> void Apply(DerivedVoidFunc func) { func(*this); }
>    }
>
>Now I also have two functions:
>
>    void baseFunc(Base& b);
>    template <class T> void derivedFunc(Derived<T>& d);
>
>If I write code that calls derivedFunc, I can replace all those calls
>with calls to baseFunc and the compiler will automatically convert the
>Derived<T>&'s to Base&'s.  The code is still legal after the change.
>
>Given this, is it reasonable to say that a DerivedVoidFunc should be
>automatically convertible into a BaseVoidFunc?  For example, should I
>be able to do this:
>
>    Derived<int> d;
>    d.Apply(baseFunc); // legal?

I believe this ought to be legal, but the ARM does not mention it.  I do not
know whether the current draft standard discusses it.  (Note that the use of a
template in the example is quite irrelevant to the point.)

I would suggest that the rule should be something like this:

A function pointer of type F may be converted to a function pointer of type G
if a> either the return type of F either is identical to that of G, or the
return type of F is of the form `D*' or `D&', that of G is of the form `B*' or
`B&' respectively, and B is an accessible base class of D and the conversion
from `D*' to `B*' is unambiguous; AND b> F and G have the same number of
parameters, and for each corresponding pair of parameters Fi and Gi, either
their types are identical, or Fi's type is of the form `B*' or `B&', Gi's type
is of the form `D*' or `D&' respectively, and B is an accessible base class of
D and the conversion from `D*' to `B*' is unambiguous.

[Whew!]

Note that the rule for parameters is "inverted" vis-a-vis the rule for the
return type!  This is, in fact, for the same reason that the rule for pointers
to members is "inverted" [ARM 4.8, p. 38] (a pointer to member being just a
funny kind of function).

-- Scott Burson
   Gyro@zeta-soft.com




Author: hopps@yellow.mmm.com (Kevin J Hopps)
Date: Fri, 3 Sep 93 18:13:30 GMT
Raw View
I have the following two classes, with the relevant portions shown.

    class Base { public:
 typedef void (*BaseVoidFunc)(Base& b);
 void Apply(BaseVoidFunc func) { func(*this); }
    };

    template <class T> class Derived : public Base { public:
 typedef void (*DerivedVoidFunc)(Derived<T>& d);
 void Apply(DerivedVoidFunc func) { func(*this); }
    }

Now I also have two functions:

    void baseFunc(Base& b);
    template <class T> void derivedFunc(Derived<T>& d);

If I write code that calls derivedFunc, I can replace all those calls
with calls to baseFunc and the compiler will automatically convert the
Derived<T>&'s to Base&'s.  The code is still legal after the change.

Given this, is it reasonable to say that a DerivedVoidFunc should be
automatically convertible into a BaseVoidFunc?  For example, should I
be able to do this:

    Derived<int> d;
    d.Apply(baseFunc); // legal?
--
Kevin J. Hopps   e-mail: kjhopps@mmm.com
3M Company   phone: (612) 737-3300
3M Center, Bldg. 235-3B-16 fax: (612) 737-2700
St. Paul, MN 55144-1000