Универсальный вариант разобрать функтор на составляющие
#include <functional>
#include <string>
template <typename F>
struct HandlerTraits;
template <typename R, typename ...Args>
struct HandlerTraits<std::function<R(Args...)>>
{
using ReturnType = R;
using ArgTypes = std::tuple<Args...>;
static constexpr std::size_t ArgCount = sizeof...(Args);
template <std::size_t N>
using NthArg = std::tuple_element_t<N, ArgTypes>;
};
template <typename T>
void processEvent(T const& handler)
{
using Traits = HandlerTraits<T>;
static_assert(std::is_same_v<typename Traits::ReturnType, void>);
static_assert(Traits::ArgCount == 2);
static_assert(std::is_same_v<typename Traits::template NthArg<0>, std::string*>);
static_assert(std::is_same_v<typename Traits::template NthArg<1>, int const&>);
}
int main()
{
processEvent(std::function<void(std::string*, int const&)>{});
}