I also do not even begin to understand why 'bool (*)(char const)' becomes 'bool (*)(char)' in any logical world. Clearly a char const is not the same as a char. Who in their right minds would make up a rule that says they are the same, whether in a function declaration or not ? They clearly are not, unless you are out to destroy the notion that top-level consts in function declarations mean anything. That is pretty easy: The function type(!) does NOT include the const of value parameters. My goto for this is godbolt and an easy template test: https://godbolt.org/z/7MvbWb3EW This is why in the function declaration you can omit the const even when you use it in the definition and if you think about it it makes sense: If the function does or does not modify a copied (i.e. by-value) parameter doesn't matter to the caller at all.
Honestly if this is now C++, something seriously has gone wrong AFAICS. No doubt I am missing something basic, but this is truly "Alice in Wonderland" stuff to me. OK, I have had my rant. In what I was working on I will just specify that T as a top-level const is disallowed. My design can get by on that, rather than come up with some tortured code that allows T as a top-level const in the sort of signature above which works in both C++14 and C++17 on up.
In short the takeaway here is: Function value parameters in function signatures are never const.