之前总结过一篇Boost之高阶函数——函数对象,介绍了几个用于处理函数对象的 Boost C++ 库。而目前C++11的标准库std已经提供了函数对象的一些功能。
根据wiki可以知道Higher order funciton的定义如下:
In mathematics and computer science, a higher-order function (also functional, functional form or functor) is a function that does at least one of the following:
- takes one or more functions as arguments (i.e., procedural parameters),
- returns a function as its result.[disputed – discuss]
All other functions are first-order functions.
一般的函数行为是:
function(arg1, arg2); // a function call
如果我们希望对象也可以有类似的功能,就必须要让它们也有可能被调用
,即,通过小括号的运用和实参的传递,这是可能的。只需要定义operator()
,并给予合适的参数类型。
class X {
public:
return-value operator() (arguments) const;
// ...
};
现在就可以把这个class对象
当做函数来调用了。
X obj;
obj(arg1, arg2); // call operator() for function object obj
// 等同于调用:obj.operator()(arg1, arg2);
Function Object
比较常见的例子有:
(1)map function, found in many functional programming languages, is one example of a higher-order function. It takes as arguments a function f and a list of elements, and as the result, returns a new list with f applied to each element from the list.
在C++里,例如:
std::transform(begin, end, result, func);
(2)Sorting functions, which take a comparison function as a parameter, allowing the programmer to separate the sorting algorithm from the comparisons of the items being sorted. The C standard function qsort is an example of this.
例如:
/* qsort example */
#include /* printf */
#include /* qsort */
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main ()
{
int n;
qsort (values, 6, sizeof(int), compare);
for (n=0; n<6; n++)
printf ("%d ",values[n]);
return 0;
}
看下C++里的用法。
// Generic lambdas provided by C++14.
#include
auto twice = [](auto f, int v)
{
return f(f(v));
};
auto f = [](int i)
{
return i + 3;
};
int main()
{
std::cout << twice(f, 7) << std::endl;
}
// Or, use std::function in C++11
#include
#include
auto twice = [](const std::function<int(int)>& f, int v)
{
return f(f(v));
};
auto f = [](int i)
{
return i + 3;
};
int main()
{
std::cout << twice(f, 7) << std::endl;
}
那么问题来了,什么时候用函数对象呢?在下面这些情况下,可以考虑使用:
函数对象是一种带状态的
函数。函数对象可以拥有成员函数和成员变量。这意味着,函数对象拥有状态。这在普通的函数中是不可能的。
每个函数对象有其自己的类型。普通的函数,唯有其签名不同时,才算是类型不同。而函数对象即使签名相同,也可以有不同的类型。我们可以将函数行为当做template参数来运用。
函数对象通常比普通函数速度快。就template概念而言,由于更多细节在编译器就已经确定,所以通常可能进行更好的优化。所以,传入一个函数对象可能获得更好的执行效能。
refer:
[1] I keep hearing a lot about functors in C++. Can someone give me an overview as to what they are and in what cases they would be useful?
[2] The C++ Standard Library v2, P.233