Topic: template and inheritance
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/04/17 Raw View
conraud@ciril.fr (Joel Conraud) writes:
>I was surprised to get the following message both on HP and SGI
>C++ 3.x compilers :
>
>CC: "template.cc", line 25: error: cannot make a Foo <A> from a class Foo <B>
>
>class A { ... };
>struct B : public A { ... };
>
>template <class X>
>class Foo {
...
>};
>
>As B is derived from A, I don't understand why a Foo<B> cannot be used
>when a Foo<A> is expected.
Because in general it would not be type-safe.
Suppose Foo has a member function f(X*):
template <class X>
class Foo {
public:
void f(X*) const;
};
Now suppose you do
int main(void) {
A a;
Foo<B> foo_b;
const Foo<A>& foo_a_ref = foo_b; // 1
foo_a_ref.f(&a); // 2
}
At point // 2, you are passing an A* to Foo<A>::f(A*), which should be
fine. But the problem is that foo_b does not have an f(A*), it only
has an f(B*), and you can't pass an A* to a function expecting a B*.
So this would cause problems.
In general, a bag-of-apples is-NOT-a bag-of-fruit, even though an
apple is-A fruit. The reason is that there are things you can do to
a bag-of-fruit that you can't do to a bag-of-apples, such as putting
an orange into the bag.
>Is this the standard behaviour ?
Yes.
--
Fergus Henderson | As practiced by computer science, the study of
fjh@cs.mu.oz.au | programming is an unholy mixture of mathematics,
http://www.cs.mu.oz.au/~fjh | literary criticism, and folklore. - B. A. Sheil
Author: conraud@ciril.fr (Joel Conraud)
Date: 1995/04/13 Raw View
Hello,
I was surprised to get the following message both on HP and SGI
C++ 3.x compilers :
CC: "template.cc", line 25: error: cannot make a Foo <A> from a class Foo <B>
with the following code :
class A {
public:
int i;
};
struct B : public A {
public:
int j;
};
template <class X>
class Foo {
private:
X x_;
};
void make_something_with(const Foo<A>&) {
}
void main(void) {
Foo<A> a_Foo_of_A;
Foo<B> a_Foo_of_B;
make_something_with(a_Foo_of_A);
make_something_with(a_Foo_of_B);
return;
}
As B is derived from A, I don't understand why a Foo<B> cannot be used
when a Foo<A> is expected.
Is this the standard behaviour ? I have not found something related
to this issue in the references I have.
Thanks for your help,
-----
Joel CONRAUD
54501 VANDOEUVRE LES NANCY (France)
Tel : (33) 83.50.30.25
Fax : (33) 83.51.23.12
E-Mail : conraud@ensg.u-nancy.fr
Author: bflorman@indy.net (Bruce A. Florman)
Date: 1995/04/14 Raw View
: As B is derived from A, I don't understand why a Foo<B> cannot be used
: when a Foo<A> is expected.
class Animal { ... };
class Dog : public Animal { ... };
class Cat : public Animal { ... };
template <class T>
class BoxOf
{
public:
void PutIn (T*);
T* TakeOut ();
...
};
...
BoxOf<Dog> aBox;
BoxOf<Animal> & sameBox = aBox; // Dog is derived from Animal, so why not?
Cat* aCat = new Cat;
sameBox.PutIn(aCat); // Cat is derived from Animal, so this should work.
Dog* aDog = aBox.TakeOut(); // Oops!
...
Do you see the problem?
--Bruce