4 ms·
> C++’s classical OOP system supports “covariant return types,” but it does not support “contravariant parameter types.” The problem in the authors "Animal doc
by nly 8y ago
> C++’s classical OOP system supports “covariant return types,” but it does not support “contravariant parameter types.”
The problem in the authors "Animal doctor" example is that the universe of all possible animal types is practically unbounded, or "open".
What you want here are "open multimethods": something Bjarne Stroustrup has wanted in C++ for a long time[0] but have been implemented in library form[1].
Of course, the thing to remember is that, as soon as you go to an open multiple dispatch arrangement, you will lose much of the static safety guarantees that the type-system affords us. There will always be runtime/dynamic type checking, and a runtime failure case.
If you don't want an open system, then some combination of templates for static polymorphism and strategic type-erasure will get the job done. e.g. use boost::variant and multivisitation [2], and the compiler will instantiate all O(n^2) methods for you.
[0] http://www.stroustrup.com/multimethods.pdf http://www.stroustrup.com/multimethods.pdf (2007)
[1] https://github.com/jll63/yomm2/blob/master/examples/asteroids.cpp https://github.com/jll63/yomm2/blob/master/examples/asteroid...
[2] https://www.boost.org/doc/libs/1_69_0/doc/html/variant/tutorial.html#variant.tutorial.multi-visitation https://www.boost.org/doc/libs/1_69_0/doc/html/variant/tutor...
- malkia 8y agoI've learned about multi-dispatch from Common Lisp, and back then was prototyping a turn-based game, where I can have multi-method working: Outcome attack( RangeBaseUnit attackingUnit, MeleeBasedUnit defendingUnit ) and also Outcome attack( MeleeBasedUnit attackingUnit, RangeBasedUnit defendingUnit ) it was the most elegant approaches I've seen. Not that you can't do it in C++, but not as straightforward as it was in CLOS.
- zenexer 8y agoIn OOP, isn't that essentially just overloading? In many OO languages, you could write both of those lines as-is (with corresponding method bodies) and have valid code. They'll typically be treated as two separate methods that just happen to have the same name.
- oweiler 8y agoThe main difference is that overloading is resolved at compilation time whereas multi methods are resolved at runtime.
- pjmlp 8y agoNo because multi-mthods don't have a self/this pointer as such, rather they are dispatched at runtime taking into account the actual types of each parameter.
- skocznymroczny 8y agoIn OOP, I think the closest equivalent would be the visitor pattern.
- int_19h 8y agoThe example is just that, an example. There's no logical reason to not have contravariant parameter types - they follow directly from the Liskov substitution principle. The reason why C++ doesn't have them is because they are relatively harder and more costly to implement than return types (consider that multiple inheritance means that pointer-to-derived often needs to be offset to be used as pointer-to-base).