我有一个简单的问题,但我不知道如何解决它,因为我从未在C ++中使用过仿函数。
我想做那样的事情(这只是一个例子):
class MyClass
{
void applyFunction(myFunction); /* WRONG SYNTAX */
double *_x;
unsigned int *_size;
};
void MyClass::applyFunction(myFunction) /* WRONG SYNTAX */
{
for (unsigned int i = 0; i < _size; ++i)
myFunction(_x[i], 10.);
}
class OtherClass
{
void myFunction1(double x, double lim);
void myFunction2(double x, double lim);
std::vector _v;
};
void OtherClass::myFunction1(double x, double lim)
{
_v.clear();
if (x > lim)
_v.push_back(x);
}
void OtherClass::myFunction2(double x, double lim)
{
_v.clear();
if (x < lim)
_v.push_back(x);
}
int main()
{
MyClass myClass;
OtherClass otherClass;
myClass.applyFunction(otherClass.myFunction1); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
myClass.applyFunction(otherClass.myFunction2); /* WRONG SYNTAX */
std::cout<<otherClass._v.size()<<std::endl;
return 0;
}
使用functor / std :: functions的正确语法是什么?
非常感谢!
答案 0 :(得分:4)
我会告诉你你想要使用仿函数。只是为了笑容,我还假设你想要以“正确”的方式做到这一点,而不仅仅是找到一个可以让它编译的语法(并且可能运行,也许可以做你想要的)。
在这种情况下,标准库已经有了算法来支持你正在做的很多事情(特别是在C ++ 11中)。要将符合某些条件的数据复制到目标向量中,您需要std::copy_if
(尽管在C ++ 98/03中缺少这一点 - 您必须颠倒比较的意义并使用std::remove_copy_if
)
使用它,你的代码就像这样:
template <class T>
class less_than {
T limit;
public:
less_than(T lim) : limit(lim) {}
bool operator()(T const &val) { return val < limit; }
};
std::copy_if(source.begin(),
source.end(),
std::back_inserter(target),
less_than<int>(10));
但是,如果你有C ++ 11可用,那么使用lambda可能更方便:
std::copy_if(source.begin(),
source.end(),
std::inserter(target),
[](int v) { return v < 10;});
lambda基本上只是让编译器为你生成一个匿名仿函数类的一种方式,所以两者之间没有太大的区别,但lambda显然可以节省相当多的输入。
如果你坚持使用C ++ 03,你基本上只是反转比较:
template <class T>
class greater_than {
T limit;
public:
bool operator()(T const &val) {
return val > limit;
}
};
std::remove_copy_if(src.begin(),
src.end(),
std::back_inserter(dst),
greater_than(10));
或者,您可以非常轻松地编写自己的copy_if
- 它主要是通过监督而被排除在C ++ 98/03之外,而不是因为它需要语言无法提供的任何内容,或类似的内容(虽然我记得,完全正确地处理所有边界条件可能有点棘手)。
对于它的价值,我还应该注意标准库确实有std::less
和std::greater
,所以我上面给出的less_than
和greater_than
仿函数都是真的很有必要。不幸的是,他们只是进行比较,所以要像我们在这里一样使用它们,你必须使用std::bind1st
或std::bind2nd
来比较常量:
std::remove_copy_if(src.begin(),
src.end(),
std::ostream_iterator<int>(std::cout, "\n"),
std::bind1st(std::less<int>(), 10));
答案 1 :(得分:1)
void applyFunction(std::function<void(double, double)>);
// ...
applyFunction(std::bind(&OtherClass::myFunction1, &otherClass));