在尝试使用函数指针时,我想知道是否有一种方法可以将模板函数指针作为参数传递,它使用模板的一个实例作为其参数之一。例如,我有以下模板函数:
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,但是因为函数match应该得到const T&,所以如果可能的话,我真的不确定如何排序。
编辑:我修复了第一个注释中提到的匹配调用,但我不确定要将什么作为参数传递给countMod。我猜它有点像bool(*match)(int, **???**),但我不确定。
发布于 2016-11-26 04:57:41
更简单方法是模板化你的方法
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>);发布于 2016-11-26 06:30:50
正如您在对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。我们现在所做的不是直接传递函数,而是在传递之前使用λ绑定其中一个参数。在使用高阶函数时,这类事情很常见。
当然,在这一点上您可能注意到count看起来非常通用。它实际上只在容器参数中是非泛型的,因为它特别需要一个整数向量。如果我们将该部分也设为通用的,那么我们在标准库中就会得到一个函数:count_if。您的问题也可以通过以下方式解决:
auto c = std::count_if(v.begin(), v.end(),
[nmod = Num(mod)] (int x) { return match(x, nmod); });https://stackoverflow.com/questions/40811783
复制相似问题