5 ms·
> For example, you can't pass the OP's "add" around as a function pointer. To be fair, in C++ you have to say which overload you want to point a function poin
by maxlybbert 11y ago
> For example, you can't pass the OP's "add" around as a function pointer.
To be fair, in C++ you have to say which overload you want to point a function pointer at. So the fact that you have to specify the real function you want to point at, in C, doesn't seem unreasonable.
- kazinator 11y agoNo, you don't have to say that in C++ and there isn't any way to, in fact. // Well, you do say it ... with type! int (*ptr)(int, int) = add; This will take the address of add(int, int) and not some other add like add(double, double). There is no explicit way to refer to one or the other. You're right in that we can't point to the collection of add functions as such. There is no generic function add of which the overloads are its implementations, such that we can have a pointer to this generic add aggregate and have ptr(a, b) be subject to overload resolution. I think that if you want to be able to construct an object ptr out of a set of plain functions, such that ptr(a, b) chooses among those functions based on arguments, that may be doable. Just not with a plain function pointer.
- maxlybbert 11y agoYou seem to have changed your mind while writing your response, and you appear to have come to the same conclusion I did. Personally, when I learned about _Generic, I wondered why the C committee hadn't just adopted C++-style overloading. I'm convinced the reason is to avoid name mangling. The end result is that the programmer does the name mangling "by hand," with natural consequences for doing so. However, there are some important points, which make _Generic both more flexible than C++ overloading in some ways, and less flexible in other ways: * _Generic only dispatches based on a single parameter. * _Generic doesn't have to expand to a function call; it could expand to a format string, for instance (although if a macro, FOO, expands to a string literal you can't put FOO(X) next to another string literal and expect the compiler to join the two strings). * _Generic doesn't consider type conversions when doing the dispatching. * _Generic dispatching can be as complex as the programmer wishes (e.g., _Generic(X), switch (sizeof(X)) ...); yes, you start with type, but you don't have to limit yourself to exact matches. * _Generic can have a "default:" branch; this is possible in C++ but not obvious (have one overload take "..." to guarantee it will be the worst match, and only chosen when there is no other option).