首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当模板用作参数时,将指针传递给template-function

当模板用作参数时,将指针传递给template-function
EN

Stack Overflow用户
提问于 2016-11-26 04:16:18
回答 2查看 412关注 0票数 0

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

代码语言:javascript
复制
template<class T>
bool match(int i, const T& M){
    return i%M.val==0;
}

它最终将把下面的类作为T:

代码语言:javascript
复制
class Num{
public:
   int val;
   Num(int n): val(n) {}
};

(这只是一个训练代码,我当然不会用它来做什么。)

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

代码语言:javascript
复制
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,但是因为函数match应该得到const T&,所以如果可能的话,我真的不确定如何排序。

编辑:我修复了第一个注释中提到的匹配调用,但我不确定要将什么作为参数传递给countMod。我猜它有点像bool(*match)(int, **???**),但我不确定。

EN

回答 2

Stack Overflow用户

发布于 2016-11-26 04:57:41

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

代码语言:javascript
复制
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;
}

一种更具描述性的方式是

代码语言:javascript
复制
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;
}

在这两种情况下都调用它

代码语言:javascript
复制
countMod(v, mod, &match<Num>);
票数 1
EN

Stack Overflow用户

发布于 2016-11-26 06:30:50

正如您在对Jarod42的回答的注释中所指出的那样,没有真正的理由传入mod,因为您使用mod所做的唯一事情就是将其反馈给也将被传入的函数。所以合理的做法就是重构你的代码:

代码语言:javascript
复制
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;
}

现在,您只需执行以下操作:

代码语言:javascript
复制
int mod = 3; // or whatever
auto c = count(v, [nmod = Num(mod)] (int x) { return match(x, nmod); });

请注意,这需要C++14,但您可以轻松地将其修改为使用11。我们现在所做的不是直接传递函数,而是在传递之前使用λ绑定其中一个参数。在使用高阶函数时,这类事情很常见。

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

代码语言:javascript
复制
auto c = std::count_if(v.begin(), v.end(), 
           [nmod = Num(mod)] (int x) { return match(x, nmod); });
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40811783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档