The syntax like
int main( void )
is just a device used in C to indicate that a function does not have any
arguments. It doesn't mean that there is an argument of type `void`. And
it's a literal syntax, where the keyword `void` could just as well have
been `__gah__` or say `noargs` or whatever, so you can't, say, define
`using X = void;` and write `int main( X )`, just as you could not have
defined `using X = __gah__;`, because `__gah__` isn't a type here.
C++ supports the syntax for compatibility, but otherwise it's
meaningless in C++, a pure C-ism, because (unlike in C) in C++ `int
main()` states directly that the function has no arguments.
So, that's why the code doesn't compile: there is just no such thing as
an argument of type `void`. The C-ism syntax is just misleading. Though,
for convenience, one /can/ do `return void()` for a function returning
`void`, proving that ~nothing's free of special case rules in C++.
Technically you can save the current code by, for example, introducing a
traits template whose specializations map from `req_N_t::res_t` to some
function type used for your callback argument.
But I would work on the design instead of the coding.
Because it sounds a bit fishy to me to have callbacks with different
number of arguments. I'd work on unifying that.
Cheers!,
- Alf