The best way for me to describe what I am asking is a simple example.
template<typename T>
void execute_example(T* begin, T* end) 
{
    T val = 10 * 0.8;
    while (begin != end) 
    {
        *begin = val;
        val *= 0.8;
        ++begin;
    }
}
using var_t = std::variant<float*, int*, double*>;
// I am just going to assume the type in input is *float to save lines
template<class UnaryOperator>
void my_function(UnaryOperator unary_op, var_t input, size_t size) 
{
    if (input.index() != 0)
        return;
    float* begin = std::get<0>(input);
    float* end = begin + size;
    unary_op<float>(begin, end);
}
int main() 
{
    float* vals = new float[](10);
    my_function(execute_example, vals, 10); // How can I pass execute_example here ??
    delete[] vals;
}
What I am basically trying to figure out how to do is pass a function that needs a template as a function argument. For example, this would work, if instead of a template argument I just set T to float:
void execute_example(float* begin, float* end) 
{
    float val = 10 * 0.8;
    while (begin != end) {
        *begin = val;
        val *= 0.8;
        ++begin;
    }
}
using var_t = std::variant<float*, int*, double*>;
// I am just going to assume the type in input is *float to save lines
template<class UnaryOperator>
void my_function(UnaryOperator unary_op, var_t input, size_t size)
{
    if (input.index() != 0)
        return;
    float* begin = std::get<0>(input);
    float* end = begin + size;
    unary_op<float>(begin, end);
}
int main() 
{
    float* vals = new float[](10);
    my_function(execute_example, vals, 10); // works!!
    delete[] vals;
}
Even if I changed my_function to the following, it still wouldn't work.
template<typename T>
void my_function(std::function<void(T*,T*)> unary_op, var_t input, size_t size)
Is there a way to do this? It seems like there should be because the following is also valid:
template<class UnaryOperator>
void my_function(UnaryOperator&& unary_op, var_t input, size_t size) 
{
    if (input.index() != 0)
        return;
    float* begin = std::get<0>(input);
    float* end = begin + size;
    std::forward<UnaryOperator>(unary_op)(begin, end);
}
int main()
{
    float* vals = new float[10];
    my_function([](auto* a, auto* b) {
        typedef typename std::remove_pointer<decltype(a)>::type value_t;
        value_t val = 10 * 0.8;
        while (a != b) {
            *a = val;
            val *= 0.8;
            ++a;
        }
    }, vals, 10);
    delete[] vals;
}
Which would do the same thing, and I would not have to specify a type.
 
     
    