函数对象
✍ dations ◷ 2025-06-20 02:16:55 #函数对象
函数对象(function object)是一个程序设计的对象允许被当作普通函数来调用。
函数对象与函数指针相比,有两个优点:第一是编译器可以内联执行函数对象的调用;第二是函数对象内部可以保持状态。
函数式程序设计语言还支持闭包,例如,first-class函数支持在其创建时用到的函数外定义的变量的值保持下来,成为一个函数闭包。
传统的C/C++函数指针:
#include <stdlib.h>/* Callback function, returns < 0 if a < b, > 0 if a > b, 0 if a == b */int compareInts(const void* a, const void* b){ return *(const int *)a - *(const int *)b;}...// prototype of qsort is// void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));...int main(void){ int items = { 4, 3, 1, 2 }; qsort(items, sizeof(items) / sizeof(items), sizeof(items), compareInts); return 0;}
C++中,函数对象是定义了的类对象,称作。
// comparator predicate: returns true if a < b, false otherwisestruct IntComparator{ bool operator()(const int &a, const int &b) const { return a < b; }};...// An overload of std::sort is:template <class RandomIt, class Compare>void sort(RandomIt first, RandomIt last, Compare comp);...int main(){ std::vector<int> items { 4, 3, 1, 2 }; std::sort(items.begin(), items.end(), IntComparator()); return 0;}
除了类类型函数对象,还有其他类型的函数对象,如使用成员函数指针或模板。C++11允许使用具有闭包功能的匿名函数。
C++的STL中的众多algorithm,非常依赖于函数对象处理容器的元素。因此,STL预定义了许多函数对象、谓词(predicate)、以及用于复合(composite)函数对象的binder、member function adapter、 pointer to function adapters、 negaters、 function objects base structure。由于STL中的algorithm使用函数对象作为参数时,一般都是传值调用,所以函数对象应该仔细设计其。
C++98在头文件functional中定义了下述函数对象:plus<type>() 结果为(param1 + param2)minus<type>() 结果为(param1 - param2)multiplies<type>() 结果为(param1 * param2)divides<type>() 结果为(param1 / param2)modulus<type>() 结果为(param1 % param2)
返回布尔值(或者可以隐式转换为布尔值)的函数对象。用于STL中的algorithm时,谓词应该是无状态的( stateless)函数对象,即谓词的结果不依赖于内部的数据成员。这是因为STL中的algorithm不保证内部实现时对传入的谓词要复制多少次。C++98在头文件functional中定义了下述谓词:
用于组合(combine)、变换(transform)、操作(manipulate)函数对象、特定参数值、或者特定函数。进一步细分为:
C++98在头文件functional中定义了两个函数bind1st与bind2nd,返回值为binder1st、binder2nd类型。用于把二元函数对象分别绑定第一个、第二个参数后成为单元函数对象。
negate把一个作为谓词的函数对象取反。C++98在头文件functional中定义了两个函数not1与not2,返回值为unary_negate、binary_negate类型。
Member function adapter用于把类的成员函数用作STL中的algorithm的参数。C++98在头文件functional中定义了:
函数指针适配器(Pointer to function adapter)是把函数指针包装为一个函数对象,以便STL中的algorithm用函数对象作为统一的参数类型,不用再考虑以函数指针作为传入参数的情形。C++98在头文件functional中定义了:
函数对象基类(Function Object Base)定义在头文件functional中,用作STL的预定义的与函数对象有关的各个类的基类,其中定义了几个类型,分别表示函数调用的各个参数类型、结果类型。
Python程序设计中,函数是作为头等对象(first-class object),可以如同普通的字符串、数值、list等对象那样操作。这使得大部分编写函数对象都是不必须的。
任何对象定义了__call__()
方法,就具有了可以当作函数调用的语法。例如下面的做累加的类
class Accumulator(object): def __init__(self, n): self.n = n def __call__(self, x): self.n += x return self.n