Topic: Contravariant parameter types and function overriding
Author: jefolts@oasis.novia.net (Jeff Folts)
Date: 1997/04/23 Raw View
Jeff Folts (jefolts@oasis.novia.net) wrote:
> Nicolas Chapados (chapados@nortel.ca) wrote:
> > I would like some insight as to why C++ does not support contravariance
> > of the parameter types of overridden virtual functions.
>
> There is a fairly good explanation of why this was
> not done in:
>
> "The Design and Evolution of C++", Bjarne Stroustrup
> Section 13.7.1 - Relaxation of Argument Rules
Sorry, my response above refers to covariance and not
contravariance. :-(
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/04/19 Raw View
Herb Sutter <herbs@cntc.com> writes:
> "Nicolas Chapados" <chapados@nortel.ca> wrote:
> >class A { ... };
> >class B : public A { ... };
> >
> >class X { virtual void foo(B*); };
> >class Y : public X { virtual void foo(A*); };
> >
> >In the above, why does not C++ allow Y::foo to override X::foo? This
> >situation is type-safe: the derived function called through a base
> >pointer will always be passed a B*, which IS-An A*.
>
> I wasn't around when this was discussed, but my first gut reaction is that it
> can be done without additional language support using a forwarding function:
class Y : public X {
virtual void foo(B* p) { foo (convert<A*>(p)); }
virtual void foo(A*);
};
This argument also apply to covariance:
class X {
virtual A* fooA() { return foo (); }
A* foo();
};
class Y : public X {
virtual A* fooA() { return fooB (); } // final - don't override
virtual B* fooB() { return foo (); }
B* foo();
};
class Z : public Y {
virtual B* fooB() { return fooC (); } // final - don't override
virtual C* fooC() { return foo (); }
C* foo();
};
> On the other hand, I believe [covariant] return types were specifically
> allowed in the language at least in part because there was no easy way to get
> the same effect without a language extension, and it was a useful effect
> (e.g., it got rid of two thirds of the casts in one large multi-100KLOC
> project).
For functions like clone, a template can be used:
template <class T>
T* clone (T* x)
{
return static_cast<T*> (x.clone ()); // only one cast here
}
assuming all clone function are overiden to return something
of the type they are applied on.
--
Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: herbs@cntc.com (Herb Sutter)
Date: 1997/04/15 Raw View
"Nicolas Chapados" <chapados@nortel.ca> wrote:
>class A { ... };
>class B : public A { ... };
>
>class X { virtual void foo(B*); };
>class Y : public X { virtual void foo(A*); };
>
>In the above, why does not C++ allow Y::foo to override X::foo? This
>situation is type-safe: the derived function called through a base
>pointer will always be passed a B*, which IS-An A*.
I wasn't around when this was discussed, but my first gut reaction is that it
can be done without additional language support using a forwarding function:
class Y : public X {
virtual void foo(B* p) { foo(static_cast<A*>(p)); }
virtual void foo(A*);
};
Clumsier, but it works. See D&E pages 295-297 for some related discussion
about this.
On the other hand, I believe contravariant return types were specifically
allowed in the language at least in part because there was no easy way to get
the same effect without a language extension, and it was a useful effect
(e.g., it got rid of two thirds of the casts in one large multi-100KLOC
project).
---
Herb Sutter (mailto:herbs@cntc.com)
Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada L5K 2N6
Tel 416-805-9088 Fax 905-822-3824
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: herbs@cntc.com (Herb Sutter)
Date: 1997/04/15 Raw View
herbs@cntc.com (Herb Sutter) wrote:
>On the other hand, I believe contravariant return types were specifically
^^^^^^
Typo... this should be "covariant" of course.
---
Herb Sutter (mailto:herbs@cntc.com)
Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada L5K 2N6
Tel 416-805-9088 Fax 905-822-3824
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: jefolts@oasis.novia.net (Jeff Folts)
Date: 1997/04/15 Raw View
Nicolas Chapados (chapados@nortel.ca) wrote:
> I would like some insight as to why C++ does not support contravariance
> of the parameter types of overridden virtual functions.
There is a fairly good explanation of why this was
not done in:
"The Design and Evolution of C++", Bjarne Stroustrup
Section 13.7.1 - Relaxation of Argument Rules
It basically says that it would be too expensive to
check run-time type information on every argument of
virtual function calls . . . and that RTTI should be
explicitly employed where this functionality is
required. B-)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Nicolas Chapados" <chapados@nortel.ca>
Date: 1997/04/14 Raw View
I would like some insight as to why C++ does not support contravariance
of the parameter types of overridden virtual functions. For example,
consider the following parallel hierarchies:
class A { ... };
class B : public A { ... };
class X { virtual void foo(B*); };
class Y : public X { virtual void foo(A*); };
In the above, why does not C++ allow Y::foo to override X::foo? This
situation is type-safe: the derived function called through a base
pointer
will always be passed a B*, which IS-An A*.
I am aware that the language has been modified to permit covariant
return types. Why not go further, and permit contravariant parameter
types?
[[An hypothesis is that permitting it would make the already-complex
overload resolution rules even more complex.]]
I would appreciate opinions from language historians and lawyers.
Many thanks!
+ Nicolas Chapados
---
Nicolas Chapados Home: n.chapados@ieee.ca
Nortel Technology, Montreal, Canada Work: chapados@nortel.ca
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]