C++11系列——函数对象(Function Object)

之前总结过一篇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:

  1. takes one or more functions as arguments (i.e., procedural parameters),
  2. 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;
}

那么问题来了,什么时候用函数对象呢?在下面这些情况下,可以考虑使用:

  1. 函数对象是一种带状态的函数。函数对象可以拥有成员函数和成员变量。这意味着,函数对象拥有状态。这在普通的函数中是不可能的。

  2. 每个函数对象有其自己的类型。普通的函数,唯有其签名不同时,才算是类型不同。而函数对象即使签名相同,也可以有不同的类型。我们可以将函数行为当做template参数来运用。

  3. 函数对象通常比普通函数速度快。就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

你可能感兴趣的:(C11/C++11,C/C++)