Many thanks all for the lively roller-coaster of useful comments. Somebody on Reddit, where I asked the same question, under the user name "TheTiefMaster", dropped this "one liner":
// also works as C
char whatever(unsigned k) { return char(k); } char(*F)(unsigned) = whatever;
Let me clarify: I do understand these are two statements on one line. And no there is no type in here, but one function pointer pointing to the same function. The usage:
auto x = whatever(65); // 'A'
auto y = F(66); // 'B'
Then I figured the following will make the function definition and its type declaration:
// FP is a type of function whoever
char whoever(unsigned k) { return 'A'; } typedef char(*FP)(unsigned) ;
Calling whoever behaves as expected
auto w = whoever(42) ; // 'A'
FP is where it starts getting interesting. FP is a type, and as it turns out one can cast to the type.
// using FP as a type
// c++ style type cast
// empty cast returns nullptr
auto fun = FP();
// calling fun() above crashes
// but it is "invocable" as per C++ rules
static_assert(std::is_invocable_v<P2F()>);
Passing any argument to this cast, works and returns non null address:
// update: this compiles only on MSVC
// and is a bug
auto fun = FP(42);
// type of fun is char (*) (unsigned)
Calling the result of this fun crashes, obviously:
// reading access violation
fun(123) ;
This cast with an instance from any required function, works:
auto fun = FP(whatever);
// works, obviously
fun(65) ; // 'A'
To use this knowledge we will use the static_cast to safely cast to what we can call. C++ type cast is too forceful, just like C style type cast is.
// does not compile
// fun is the wrong type and can not be called
auto fun = static_cast<FP>(42);
// does compile, fun is safe to call
auto fun = static_cast<FP>(whatever);
// works, obviously
fun(65) ; // 'A'
This investigation is obviously far from over. I shall proceed with it, elsewhere.
Update:
using FP = char (*)(int) ;
// must not compile, compiles under MSVC
auto oops = FP(42) ;
Is the bug in MSVC, I reported it today.