See how Rust or C# do generics, as well as Java or Scala (I think this feature is also called "Concepts" in C++, but I'm not sure it supports it yet).
You specify a type parameter, and then statically write out that it has to adhere to a certain interface/trait. This analysis is done at compile time, not runtime as with virtual dispatch.
Did you mean ad-hoc polymorphism?