There is, of course, a problem with the previous example. It may even strike some as quite subtle, the first time they think about it. Let’s try invoking our “imbibe” operation in a context where the type of the operands cannot be statically determined.

In fact, this code not only will not run, it won’t even compile. This is because while the first operand to imbibe, the receiver, the Carouser, is dispatched using runtime polymorphism, the second, the Libation, is resolved using static overloading, which is a horse of an entirely different color.

The implementations we’ve seen are really nothing but “name mangled” single-dispatch invocations under the hood.