当模板用作参数时,将指针传递给模板函数

时间:2016-11-25 20:16:18

标签: c++ templates pointers

在尝试使用函数指针时,我想知道是否有一种方法可以将模板函数指针作为参数传递给模板函数指针,该指针使用模板实例作为其参数之一。例如,我有以下模板功能:

template<class T>
bool match(int i, const T& M){
    return i%M.val==0;
}

最终将以下课程作为T:

class Num{
public:
   int val;
   Num(int n): val(n) {}
};

(它只是一个训练代码,我当然没有使用它)

现在,我有以下函数,它基本上是count_if的实现:

int countMod(const vector<int>& v, int mod, **???**){
  Num nMod(mod);
  int cnt=0;
  for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
    if(match(*it, nMod)){
        cnt++;
    }
  }
  return cnt;
}

该方法应该返回mod整除的元素数。 第三个论点是我当然不确定的那个。

我想以某种方式将指针传递给模板函数match<Num>Num(mod)M

我理解将指针传递给实际上并不存在的东西是很奇怪的,因为我还没有实例化一个实际的函数,比如匹配, 但由于函数match应该得到const T&,如果可能,我真的不确定如何对其进行排序。

编辑: 我修复了第一条评论中提到的匹配调用,但我不确定将什么作为countMod的参数传递。我想它类似bool(*match)(int, **???**),但我不确定。

2 个答案:

答案 0 :(得分:1)

更简单的是将你的方法模板化

template <typename F>
int countMod(const vector<int>& v, int mod, F f)
{
  Num nMod(mod);
  int cnt = 0;
  for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
    if(f(*it, nMod)){
        cnt++;
    }
  }
  return cnt;
}

更具描述性的方式是

int countMod(const vector<int>& v, int mod, std::function<bool (int, Num)> f)
{
  Num nMod(mod);
  int cnt = 0;
  for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
    if(f(*it, nMod)){
        cnt++;
    }
  }
  return cnt;
}

并在两种情况下调用

countMod(v, mod, &match<Num>);

答案 1 :(得分:-1)

正如你在Jarod42的回答评论中指出的那样,没有真正的理由传递mod,因为你对mod做的唯一事情就是把它反馈给那个也传递给它的函数因此,合乎逻辑的做法就是重构代码:

template <typename F>
int count(const vector<int>& v, F f)
{
  int cnt = 0;
  for(vector<int>::const_iterator it=v.begin(); it!=v.end();it++){
    if(f(*it)){
        cnt++;
    }
  }
  return cnt;
}

现在,您可以执行以下操作:

int mod = 3; // or whatever
auto c = count(v, [nmod = Num(mod)] (int x) { return match(x, nmod); });

请注意,这需要C ++ 14,但您可以轻松修改它以使用11.我们现在正在做的是,不是直接传递函数,而是在传递之前使用lambda绑定其中一个参数在处理更高阶函数时,这种情况很常见。

当然,您可能会注意到count看起来非常通用。它实际上只是容器参数中的非泛型,因为它特别需要整数向量。如果我们也将该部分设为通用的,我们最终会在标准库中使用一个函数:count_if。你的问题也可以解决:

auto c = std::count_if(v.begin(), v.end(), 
           [nmod = Num(mod)] (int x) { return match(x, nmod); });