You’re basically right, dynamic polymorphism (inheritance, virtuals) is generally the right choice when the type should be allowed to change at runtime (for example in plugin architectures). Static polymorphism (templates) is a better choice if the type should only change at compile-time.
The only potential downsides to templates are that 1) they generally have to be defined in the headers (which means more code gets #included), and this often leads to slower compile-times.
But design-wise, I can’t see any problems in using templates when possible.
Which complies more with standard c++
style?
Depends on what “standard C++ style” is. The C++ standard library uses a bit of everything. The STL uses templates for everything, the slightly older IOStreams library uses inheritance and virtual functions, and the library functions inherited from C uses neither, of course.
These days, templates are by far the most popular choice though, and I’d have to say that is the most “standard” approach.