std::cout
is one of the poster children for operator overloading. Whilst the choice of the actual operator is ... questionable ..., the extensibility of <<
is massive compared to everything that came before it, and almost everything that came after it too. In addition, consider all the Matrix
and Vector
classes, iterators, function objects, all those classes with <
overloaded so they can be the key of a map
or sorted like std::string
.
Polymorphism is pretty simple. Think what life would be like if you did not have parametric polymorphism in the form of templates. Holy shit, it would be so bad. Do I either repeat this container's code for a new type, which is a hideously bad idea, or do I go with that void*, size
rubbish that can't handle complex types and is completely type unsafe? The interface of stuff like qsort
is just unusable too. Parametric polymorphism allows both code re-use and type-safety.
Or dynamic polymorphism. std::function
couldn't work without virtual functions and inheritance, and it's a pretty damn important thing. There are also embedded-end optimizations based on inheritance. It's useful whenever you need to treat different types interchangably at run-time. In addition, there are many things which are effectively dynamic polymorphism, even if they are technically not. For example, every function you call from the Windows API goes through a table of function pointers fixed up by the dynamic linker. They are polymorphic with any implementation of those functions that conforms to the same interface. What would life be like without operating system APIs? Unlivable.