什么是C++函子及其使用?

我经常听到C++中的函子。有人能给我一个关于它们是什么以及在什么情况下它们会有用的概述吗

函子几乎就是一个定义操作符()的类。这使您可以创建“看起来”像函数的对象:

//这是一个函子
结构添加{
add_x(int val):x(val){}//构造函数
int运算符()(int y)常量{返回x+y;}
私人:
int x;
};
//现在您可以这样使用它:
添加_xadd42(42);//创建函子类的实例
int i=add42(8);//并“呼叫”它
断言(i==50);//它的论点增加了42条
标准::向量<int>在;//假设它包含一组值)
标准::向量<int>out(in.size());
//将一个函子传递给std::transform,后者对每个元素调用函子
//并将结果存储到输出序列中
std::transform(in.begin()、in.end()、out.begin()、add_x(1));
断言(out[i]==in[i]+1);//尽管我

函子有两个优点。一是与常规函数不同,它们可以包含状态。上面的示例创建了一个函数,该函数在您给定的任何值上添加42。但值42不是硬编码的,它是在我们创建函子实例时指定为构造函数参数的。我可以创建另一个加法器,它只需使用不同的值调用构造函数就可以添加27。这使得它们可以很好地定制

如最后几行所示,您经常将函子作为参数传递给其他函数,如std::transform或其他标准库算法。对于常规函数指针也可以这样做,但正如我上面所说的,函子可以“自定义”,因为它们包含状态,使它们更灵活(如果我想使用函数指针,我必须编写一个函数,在其参数中正好添加1。函子是通用的,可以添加初始化它时使用的任何内容),而且它们也可能更有效。在上面的示例中,编译器确切地知道应该调用哪个函数std::transform。它应该调用add\u x::operator()。这意味着它可以内联该函数调用。这使得它的效率就像我对向量的每个值手动调用函数一样高

如果我传递了一个函数指针,编译器无法立即看到它指向哪个函数,因此除非它执行一些相当复杂的全局优化,否则它必须在运行时取消对指针的引用,然后进行调用

发表评论