📜  c++ 函数作为参数 - C++ (1)

📅  最后修改于: 2023-12-03 14:39:54.849000             🧑  作者: Mango

C++ 函数作为参数

在 C++ 中,函数也可以被传递作为参数给另一个函数使用。这种技术被称为函数指针或者函数对象。

函数指针

函数指针是一个指向函数的指针变量。当一个函数的地址被赋给一个指针变量时,该指针变量便成为了一个函数指针。

以下是一个简单的例子:

#include <iostream>

void print(int i) {
    std::cout << i << std::endl;
}

void useFunctionPointer(void (*pointer)(int)) {
    for (int i = 0; i < 5; ++i) {
        pointer(i);
    }
}

int main() {
    useFunctionPointer(print);
    return 0;
}

代码解读:

  • 函数 print 接受一个整数参数,打印该数字到标准输出。
  • useFunctionPointer 函数接受一个函数指针作为参数,这个函数指针指向与 print 相同的函数签名(即 void function(int))。
  • useFunctionPointer 函数循环 0 到 4,调用传进去的函数指针,并传递当前循环变量作为实参。
  • main 函数内,我们使用 useFunctionPointer(将函数 print 传递给它) 反复地调用 print 函数。
函数对象

如果您还不熟悉 C++ 中的面向对象编程,则建议先学习一下。在此处,我们主要关注重载函数调用运算符(即 operator())的类的使用,通常被称为函数对象。

以下是一个简单的例子:

#include <iostream>

class Test
{
public:
    void operator() (int i) const {
        std::cout << i << std::endl;
    }
};

void useFunctionObject(const Test& t) {
    for (int i = 0; i < 5; ++i) {
        t(i);
    }
}

int main() {
    Test test;
    useFunctionObject(test);
    return 0;
}

代码解读:

  • 我们定义了一个名为 Test 的类,其中有一个单独的成员函数 operator()
  • 此处的 operator()函数其实是一个函数调用运算符,用于将一个类的实例(也就是对象)作为函数来调用。当使用这个运算符时,会先创建一个匿名对象并调用其 operator() 函数。
  • useFunctionObject 函数接受一个 const Test& 类型参数,这个参数是一个 const 引用,用于指向 Test 类型的一个常量对象。
  • useFunctionObject 函数内,我们使用接收到的参数来实例化一个 Test 对象,然后循环调用它的 operator() 函数。
Lambda 表达式

Lambda 表达式是一个把函数对象作为参数传递的更便捷的方法。它们从 C++11 开始被引入,并且常用于算法和 STL 中。

以下是一个简单的例子:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};

    std::for_each(v.begin(), v.end(), [](int i) {
        std::cout << i << std::endl;
    });

    return 0;
}

代码解读:

  • std::for_each 函数是 STL 中的一个算法,用于接受一个函数对象并用它来迭代实参范围中的每个元素。
  • 此处我们使用了一个 lambda 表达式作为 std::for_each 的第三个参数,这个 lambda 表达式输出了迭代到的整数到标准输出。
总结

以上是使用函数作为参数的三种方法。其中,函数指针和函数对象都是在采用“函数作为参数”时的用于传递函数的方式。而 Lambda 则是一种更加简便的方式,如果您的编译器支持 C++11,我们强烈建议优先使用 Lambda 表达式。