317
If your compiler is gcc and you don't mind doing hand updates every time you add a new overload you can do some macro magic and get the result you want in terms of callers, it's not as nice to write... but it's possible
look at __builtin_types_compatible_p, then use it to define a macro that does something like
#define foo(a) \
((__builtin_types_compatible_p(int, a)?foo(a):(__builtin_types_compatible_p(float, a)?foo(a):)
but yea nasty, just don't
EDIT: C1X will be getting support for type generic expressions they look like this:
#define cbrt(X) _Generic((X), long double: cbrtl, \
default: cbrt, \
float: cbrtf)(X)