Great question! To make things even more annoying - C doesn't have namespaces. So people are forced to write long names like "my_struct_hash_map_t" everywhere, which makes all modern C code look like wall of text (compare too older style code "mshm_t*a = hmalloc()"). To answer honestly - I'm asking myself very pragmatic question: "do I really need a generic code?" much more often compare to C++. In game development C++ templates were used mostly for math libraries (2d/3d/4d vectors, matrices, etc) and containers (hashmap, lists, etc). If we look closely on math libraries we can make a compromise "just float is enough", and if we make such compromise then everything is simple - one don't need templates for math lib anymore, I'm currently using "gb_math.h" [1] and it works pretty good. Containers on the other hand are more challenging, the key here is to understand "can I make this work with linear (maybe static) array?" - and in most cases yes, then you don't need any containers because just arrays will do. If algorithm specific do require a hashmap or list, well, gonna use what we have: macro! It looks weird, and it is weird, but something like khash.h [2] works fine in production.
In reality what it means for me is that I need to spend time making decisions about containers, which is good for game development, as what makes games fun doesn't have any connection to templates. But it also bad for casual non-game related code. I find it much faster to just "hey load this json, do some processing, and save json back" do that in Python than trying to do in C just for sake of C. Ideally namespaces/templates and operator overloading in C would solve all this struggles, but then where C ends and C++ starts?
- [1] https://github.com/gingerBill/gb/blob/master/gb_math.h
- [2] https://github.com/attractivechaos/klib/blob/master/khash.h