нет ли безопасного способа вызова (в этом примере) toupper по указателю?
Не напрямую, только через один уровень косвенности (см. Ниже).
делает static_cast
безопасным ли указатель на функцию библиотеки std?
Нет. Это может привести к перегрузке, установленной для одной конкретной сигнатуры функции, но это не имеет никакого отношения к тому, разрешено ли вам брать адрес этой функции.
Есть ли еще один способ для достижения перечисленных ниже функций с помощью одной функции с подписью int fun(int)
Есть альтернатива, вы можете заключить вызов функции в две лямбды. Это требует небольшого изменения исходного фрагмента:
bool choice = true;
int (*fun)(int);
if (choice)
fun = [](int ch){ return std::toupper(ch); };
else
fun = [](int ch){ return std::tolower(ch); };
int t = fun('x');
Это хорошо работает, потому что обе лямбды не имеют состояния и имеют одинаковую сигнатуру, поэтому они неявно преобразуются в указатель на функцию.