C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Re: Why no contravariant argument types?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Matthew Collett
Guest





PostPosted: Fri Aug 22, 2003 3:14 pm    Post subject: Re: Why no contravariant argument types? Reply with quote



In article <vkau7rrlo3o0d9 (AT) corp (DOT) supernews.com>,
[email]drpizza (AT) anti-flash (DOT) co.uk[/email] ("DrPizza") wrote:

Quote:
struct Food
{};

struct Meat : Food
{};

struct Plants : Food
{};

struct Herbivore
{
virtual void eat(Plants&);
};

struct Carnivore
{
virtual void eat(Meat&);
};

struct Omnivore : Herbivore, Carnivore
{
virtual void eat(Food&);
};

An Omnivore should be usable wherever one has a Herbivore or a Carnivore -- it
should be substitutable. It's safe to do so.

But because contravariant arguments don't override, it isn't possible.
Omnivore::eat hides Herbivore::eat and Carnivore::eat instead.

Is there any reason for this omission?

Unlike covariant return types, contravariant arguments do not need
special-purpose language support, since you can implement them by simple
forwarding functions. For example:

struct Omnivore: Herbivore, Carnivore
{
virtual void eatAny(Food&);
virtual void eat(Meat& meat) {eatAny(meat);}
virtual void eat(Plants& plant) {eatAny(plant);}
};

or, if you really want to use the same function name:

struct Omnivore: Herbivore, Carnivore
{
virtual void eat(Food&);
virtual void eat(Meat& meat) {eat(static_cast<Food&>(meat));}
virtual void eat(Plants& plant) {eat(static_cast<Food&>(plant));}
};

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle

---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
DrPizza
Guest





PostPosted: Sun Aug 31, 2003 6:10 pm    Post subject: Re: Why no contravariant argument types? Reply with quote



"Matthew Collett" <m.collett (AT) auckland (DOT) ac.nz> wrote


Quote:
Unlike covariant return types, contravariant arguments do not need
special-purpose language support, since you can implement them by simple
forwarding functions. For example:

struct Omnivore: Herbivore, Carnivore
{
virtual void eatAny(Food&);
virtual void eat(Meat& meat) {eatAny(meat);}
virtual void eat(Plants& plant) {eatAny(plant);}
};

or, if you really want to use the same function name:

struct Omnivore: Herbivore, Carnivore
{
virtual void eat(Food&);
virtual void eat(Meat& meat) {eat(static_cast<Food&>(meat));}
virtual void eat(Plants& plant) {eat(static_cast<Food&>(plant));}
};



But one might just as well argue that one doesn't need covariant return types
and that one should just keep the return type the same in the derived class.

Or that one doesn't need compiler-supported virtual functions at all, because
one can just build a v-table manually. Or member functions, because one can
just pass "this" explicitly. Or....

The compiler supports these things so that we can clearly express intent. Why
not this one too?


--
Now Playing: DJ Ciacomix - Friendship Rocks! CD1 (D I G I T A L L Y - I M P O
R T E D - European Trance, Techno, Hi-NRG... we can't define it!)



---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Matthew Collett
Guest





PostPosted: Tue Sep 02, 2003 4:30 pm    Post subject: Re: Why no contravariant argument types? Reply with quote



In article <vkp13dj404ltee (AT) corp (DOT) supernews.com>,
[email]drpizza (AT) anti-flash (DOT) co.uk[/email] ("DrPizza") wrote:

Quote:
Unlike covariant return types, contravariant arguments do not need
special-purpose language support, since you can implement them by simple
forwarding functions.

But one might just as well argue that one doesn't need covariant return types
and that one should just keep the return type the same in the derived class.

Not a good analogy, since this loses type information that is preserved
by the special-purpose language support.

Quote:
Or that one doesn't need compiler-supported virtual functions at all, because
one can just build a v-table manually.

Not a good analogy, since in this case the workaround is not short and
simple but complicated and error-prone.

Quote:
Or member functions, because one can
just pass "this" explicitly.

A much better analogy, and there are some who think that having special
syntax for member functions was indeed unnecessary.

Quote:
The compiler supports these things so that we can clearly express intent. Why
not this one too?

I'd say that a one-line inline forwarding function _was_ a fairly clear
expression of intent.

I also suspect that trying to provide special support for contravariant
arguments would run into ambiguities. What happens when the programmer
wants to provide a new function with contravariant argument as well as
the inherited version? Note that this is currently legal (indeed, it's
what the forwarding approach does), and the solution needs to avoid
breaking existing code. What happens when the inherited argument has
multiple base classes, and the derived class provides overloads for more
than one? Neither of these are a problem for covariant returns, since
you can't overload on return type anyway.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle

---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.