C++ 什么是仿函數?

仿函數(functor)是一種封裝函數的類別,其中封裝的函數可以像一般函數一樣呼叫,但是因為他是封裝在類別中的,所以可以使用類別的封裝和繼承特性。

在 C++ 中,仿函數是通過將函數的原型封裝在類別中,並實現一個重載了括號運算子的成員函數,來實現的。這樣就可以將仿函数當作一般函數一樣使用。

例如,我們可以定義一個仿函數類別 Plus,封裝了一個加法函數:

class Plus
{
public:
  int operator()(int a, int b) const
  {
    return a + b;
  }
};

然後我們就可以像呼叫函數一樣使用這個仿函數:

Plus plus;
int result = plus(1, 2);  // result 的值是 3

 在 C++ 中,仿函數常用於將函數作為參數傳遞給其他函數。例如,我們可以寫一個函數 apply,它接受一個仿函數和一個整數陣列,並對整數陣列中的每個元素使用仿函数進行計算:

template 
void apply(Func f, int* array, size_t size)
{
  for (size_t i = 0; i < size; ++i)
  {
    array[i] = f(array[i]);
  }
}

然後我們可以使用任意的仿函數呼叫 apply 函數:

int array[5] = { 1, 2, 3, 4, 5 };
apply(Plus(), array, 5);  // array 現在是 { 2, 4, 6, 8, 10 }

仿函數也可以用於 STL 算法中,例如 std::sort 函數。我們可以傳遞一個仿函數來定義排序的順序:

#include 
#include 

std::sort(array, array + 5, std::greater());  // array 現在是 { 5, 4, 3, 2, 1 }

此外,仿函數還可以用於封裝非函數的操作,例如成員函數或操作符運算。

例如,我們可以寫一個仿函數類別封裝 std::vector 的 push_back 操作:

#include 

class VectorPusher
{
public:
  VectorPusher(std::vector& v) : v_(v) {}

  void operator()(int x) const
  {
    v_.push_back(x);
  }

private:
  std::vector& v_;
};

std::vector v;
VectorPusher pusher(v);
pusher(1);
pusher(2);
pusher(3);

它可以讓我們將函數或其他操作封裝在類別中,並像呼叫函數一樣使用。仿函數的一個主要優點是它可以接受參數和返回結果,並且可以使用類別的封裝和繼承特性。

在 C++ 中,仿函數的用途非常廣泛,例如:

将函数作为参数传递给其他函数,例如 std::sort 函数。
封装非函数的操作,例如成员函数或运算符运算。
使用類別的封裝和繼承特性,實現函數指针的功能。
此外,仿函数也有一些缺點,例如:

代码可能會變得較為複雜。
仿函數的性能通常不如直接使用函數。
仿函數不能直接使用函數指针,必须使用 std::function 或其他方法。

在 C++ 中,仿函数可以使用 std::function 模板類型來實現。std::function 是一個泛型類型,可以封裝任意可被呼叫的對象,例如函數、仿函數、Lambda 表達式等。

例如,我們可以使用 std::function 封裝一個仿函數:

#include 

std::function plus = Plus();
int result = plus(1, 2);  // result 的值是 3


//也可以使用 std::function 封裝一個 Lambda 表達式:

std::function plus = [](int a, int b) { return a + b; };
int result = plus(1, 2);  // result 的值是 3

使用 std::function 可以讓我們更方便地使用仿函數和其他可被呼叫的對象,而不用擔心底層實現的細節。

此外,C++11 標準引入了 Lambda 表達式,這是一種匿名函數的寫法。Lambda 表達式可以方便地寫出簡單的仿函數,例如:

auto plus = [](int a, int b) { return a + b; };
int result = plus(1, 2);  // result 的值是 3

Lambda 表達式可以像一般函數一樣使用,但是因為它是匿名的,所以不能再其他地方引用。

仿函數和 Lambda 表達式是 C++ 中常用的函數式编程技术,它們可以讓我們更方便地使用函数作為参数或返回值。

你可能感兴趣的:(C++,c++,开发语言)