В обоих случаях функция передается по ссылке. И обе функции имеют отношение к lvalue-ссылке на функцию print.
Используйте
std::is_function_v<std::remove_reference_t<T>>
вместо
std::is_function_v<typename std::remove_pointer_t<T>>
Вы также можете вставить такое утверждение в Обе функции
std::cout << std::is_lvalue_reference_v<decltype( t )> << '\n';
, чтобы убедиться, что функции работают с lvalue-ссылкой на rpint.
Учтите, что вам нужно включить заголовок <type_traits>
.
Если вы хотите, чтобы функции имели дело с указателями на функции, вам нужно использовать такой вызов
f1(&print);
В этом случае вторая функция должна быть объявлена как
template<typename T>
void f2( const T& t);
В противном случае Вы не можете привязывать непостоянную ссылку к rvalue.
Или вызывать функцию f2, как если вы не хотите использовать квалификатор const.
auto p = print;
f2(p);