我正在尝试创建一种简单的方法,以特殊的初始化返回指向模板函数的指针。最好的描述方式是使用实际代码。
之所以使用这样的东西,是因为在我的实际生产代码中,我有一个measure_func
函数,该函数调用一个函数并测量执行该函数所花费的时间。我正在尝试测量的函数具有非常长的模板参数,尝试获取该参数可能会使获取函数指针更加容易。
#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);
}
因此在代码中,get_float_func
返回了t<float>
的地址。在第一种情况下,t
是add
模板函数。一旦有了指针,就可以使用do_operation
EDIT1:
其背后的原因是因为对于我们的类分配,我们必须以3种不同的方式编写并行合并排序代码。使用一个线程的串行方式,用于静态拆分工作的并行方式以及用于动态拆分工作并将其分配给不同线程的线程池合并排序。这些合并排序中的每一个都位于3个不同的命名空间中,但是共享相同的函数声明。我有一个可以传递函数指针的函数,它将测量函数花费并返回它的时间。我希望能够编写如下内容:
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>{ });
}
上面的代码不起作用,因为serial :: merge_sort等不是函数指针,但是需要模板初始化。