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