Many years ago, (at least for me,) static C++ polymorphism seemed coherent. Languages such as Python relied on duck typing, where you have:
def fn(foo, bar):
foo.baz(bar.bo())
and the idea was that if it "quacked" appropriately, it was fine by the language.
In C++, conversely, you'd have to explain what "animal" it was:
void fn(foo_type foo, bar_type bar);
and for "kingdoms of families", you'd explicitly need to use the template
keyword:
template<class Foo, class Bar>
void fn(Foo foo, Bar bar);
With new features like auto ...() -> decltype
return types, but especially generic lambdas, there appears to be something much more like non-template Python-like duck typing:
[] (auto container) { return container.size(); };
My question, then, is why is the template
keyword still needed? Why not just fully embrace (optional) duck typing:
// Takes a foo_type and a bar_type
void fn(foo_type foo, bar_type bar);
// Takes some "foo-quacking" type, and a bar_type
void fn(auto foo, bar_type bar);
// Etc.