4

I am trying to create a simple way to return a pointer to a template function with a special initialization. The best way I can describe this is with actual code.

The reason I am using something like this is because in my actual production code, I have a measure_func function that calls a function and measures the time it takes to execute that function. The function I am tryng to measure has very long template parameters and trying to get this might make getting the function pointer easier.

#include <functional>
#include <cassert>

template <typename T>
T add (T a, T b) {
    return a + b;
}

template <typename T>
T sub (T a, T b) {
    return a - b;
}


template <typename F, typename ...A>
std::invoke_result_t<F> do_operation(F func, A &&...args) {
    return func( std::forward<A>(args)... );
}

/// Attempt? Doesn't work though
template<template <typename> typename T>
auto get_float_func(T t) {
    return &t<float>;
}


int main() {
    // here I can create a function or a templated struct that returns the address of add<float>
    auto float_add = get_float_func(add);

    // here get_float_func returns the address of sub<float>
    auto float_sub = get_float_func(sub);

    // that way I can more easily call do_operation like this
    float ans1 = do_operation(float_add, 1.5, 1.0);
    assert(ans1 == 2.5);
    float ans2 = do_operation(float_sub, 1.5, 1.0);
    assert(ans2 == 0.5);
}

So in the code, get_float_func returns the address of t<float>. In the first case t is the add template function. Once we have the pointer, we can invoke the result using do_operation

EDIT1:

The reason behind this is because for our class assignment we have to write a parallel merge sort code in 3 different ways. A serial way that uses one thread, a parallel way that splits the work statically, and a threadpool merge sort that dynamically splits the work and assigns it to different threads. Each of these merge sorts are in 3 different namespaces but share the same function declaration. I have a function that you can pass in a function pointer and it will measure the time that function takes and returns it. I want to be able to write something like this:

namespace serial {
    template <typename I, typename O = std::less<typename I::value_type>>
    void merge_sort(I begin, I end, O op = {  })
    { /* code */ }
}

namespace parallel {
    template <typename I, typename O = std::less<typename I::value_type>>
    void merge_sort(I begin, I end, O op = {  })
    { /* code */ }
}

namespace threadpool {
    template <typename I, typename O = std::less<typename I::value_type>>
    void merge_sort(I begin, I end, O op = {  })
    { /* code */ }
}

int main() {
    std::vector<int> data = create_random_array();
    /// I want to create something that will always return the instantiation of merge_sort<std::vector<int>::iterator, std::less<int>>
    /// function pointer
    float elapse1 = measure_func(serial::merge_sort,     data.begin(), data.end(), std::less<int>{  });
    float elapse2 = measure_func(parallel::merge_sort,   data.begin(), data.end(), std::less<int>{  });
    float elapse3 = measure_func(threadpool::merge_sort, data.begin(), data.end(), std::less<int>{  });
}

The above code does not work because serial::merge_sort and the like are not function pointers, but need template initialization.

Aryan
  • 608
  • 6
  • 15
  • @PasserBy I added my reasoning to my code. I don't know the syntax of how I would go about doing this but I wanted to make an attempt at solving the issue. – Aryan Mar 13 '19 at 11:40
  • Why not `measure_func([&]{ serial::merge_sort(data.begin(), data.end(), std::less<>{}); });`? – Passer By Mar 13 '19 at 11:42
  • @PasserBy That is a good idea. I don't know why I didn't think of that. I would still like to figure out if what I'm trying to do is possible or not. For curiosity reasons. Thank you – Aryan Mar 13 '19 at 11:45
  • You can't pass a function template as a template parameter. You would need to make `sub` and `add` template classes for this to work. It seems like the wrong approach, where Passer's suggestion in on point. – super Mar 13 '19 at 12:05

0 Answers0