有没有办法将需要模板的函数作为另一个函数的参数传递?

问题描述 投票:0回答:1

对我来说描述我所问问题的最好方法是一个简单的例子。

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);
  delete[] vals;
}

我基本上想弄清楚如何做是传递一个需要模板作为函数参数的函数。例如,如果我不使用模板参数,而是将

T
设置为 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);
  delete vals[];
}

即使我将

my_function
更改为以下内容,它仍然无法工作。

template<typename T>
void my_function(std::function<void(T*,T*)> unary_op, var_t input, size_t size)

有办法做到这一点吗?看起来应该有,因为以下也是有效的:

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;
}

这会做同样的事情,而且我不必指定类型。

c++ templates lambda std-function
1个回答
1
投票

函数模板只是函数集的蓝图,调用者可能会在某个时刻调用它。在它没有被聚合类型实例化之前,你不能脱掉任何东西并将指针传递给它的函数,到任何地方。

此外,即使您也使用

std::function
,问题仍然存在。它所需要的只是一个显式的模板参数。我建议如下,这也不需要
std::variant

template<class UnaryOperator, typename T>
void my_function(UnaryOperator unary_op, T* input, size_t size) ,
{
    unary_op(input, input + size);
}

int main() 
{
    // use std::vector<float> or smart pointers here (If applicable)
    float* vals = new float[10]{}; 

    my_function(&execute_example<float>, vals, 10);

    delete[] vals;
}

或者将

execute_example
作为 通用 lambda

inline static constexpr auto execute_example = [](auto* begin, auto* end)
{
    // .....
};

template<class UnaryOperator, typename T>
void my_function(UnaryOperator unary_op, T* input, size_t size) 
{
    unary_op(input, input + size);
}

int main() 
{
    float* vals = new float[10] {};

    // Use std::vector<float> or smart pointers here (if applicable)
    my_function(execute_example, vals, 10);

    delete[] vals;
}

在 godbolt.org 中查看演示

© www.soinside.com 2019 - 2024. All rights reserved.