C++ 中将函数作为参数传递

C++ 中将函数作为参数传递

1. 通过指针传递函数

函数可以通过传递函数的地址来作为参数传递;简而言之,就是通过指针实现这一点。

示例代码

cpp 复制代码
#include <iostream>
using namespace std;

// 定义加法和减法函数
#include <iostream>
#include <string>
using namespace std;

// 定义拼接字符串的函数
string concatenate(const string& str1, const string& str2) {
    return str1 + str2;
}

// 定义转换成大写字母的函数
string to_uppercase(const string& str) {
    string result = str;
    for (auto& ch : result) {
        ch = toupper(ch);
    }
    return result;
}

// 函数接受指向函数的指针作为参数
string invoke(const string& str1, const string& str2, string (*f)(const string&, const string&)) {
    return f(str1, str2);
}

int main() {
    string str1 = "Hello, ";
    string str2 = "World!";
    
    // 将 concatenate 函数的指针作为参数传递
    cout << "Concatenated String: ";
    cout << invoke(str1, str2, &concatenate) << '\n';  // 输出拼接的字符串

    // 将 to_uppercase 函数的指针作为参数传递
    cout << "Uppercase String: ";
    cout << invoke(str1, str2, &to_uppercase) << '\n';  // 输出转换成大写的字符串

    return 0;
}

输出:

复制代码
Concatenated String: Hello, World!
Uppercase String: HELLO, WORLD!

说明:

在这个例子中,concatenate 和 to_uppercase 函数通过指针传递给 invoke 函数。

2. 使用 function<> 包装器

在 C++11 中,std::function 类模板可以将函数作为对象传递,使得将函数作为参数变得更加灵活。

示例代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

// 定义比较函数
bool greater_than(int x, int y) { return x > y; }  // 大于比较
bool less_than(int x, int y) { return x < y; }  // 小于比较

// 函数接受 std::function 对象作为参数
bool invoke(int x, int y, function<bool(int, int)> f) {
    return f(x, y);
}

int main() {
    int a = 20, b = 10;
    
    // 传递比较函数作为 std::function 对象
    cout << "Is " << a << " greater than " << b << "? ";
    cout << (invoke(a, b, &greater_than) ? "Yes" : "No") << '\n';  // 输出大于比较结果

    cout << "Is " << a << " less than " << b << "? ";
    cout << (invoke(a, b, &less_than) ? "Yes" : "No") << '\n';  // 输出小于比较结果

    return 0;
}

输出:

复制代码
Is 20 greater than 10? Yes
Is 20 less than 10? No

说明:

  • 在这个例子中,greater_than 和 less_than 函数通过 std::function 被传递给 invoke 函数,以进行数字比较。

  • std::function<bool(int, int)> 是一个可以接收任何具有相同签名(bool(int, int))的函数对象的容器。

3. 使用 Lambda 表达式

Lambda 表达式是 C++ 提供的一种内联函数的简洁方式,可以在需要函数作为参数的地方直接定义匿名函数。

示例代码

cpp 复制代码
#include <functional>
#include <iostream>
using namespace std;

// 函数接受 std::function 对象作为参数
int invoke(int x, int y, function<int(int, int)> func) {
    return func(x, y);
}

// 主函数
int main() {
    // 使用 Lambda 表达式进行加法操作
    cout << "Addition: ";
    int k = invoke(20, 10, [](int x, int y) -> int { return x + y; });
    cout << k << '\n';  // 输出加法结果

    // 使用 Lambda 表达式进行减法操作
    cout << "Subtraction: ";
    int l = invoke(20, 10, [](int x, int y) -> int { return x - y; });
    cout << l << '\n';  // 输出减法结果

    return 0;
}

输出:

复制代码
Addition: 30
Subtraction: 10

说明:

  • Lambda 表达式提供了一种非常简洁的方式来定义函数对象。在 invoke 函数中,我们直接将一个 Lambda 表达式传递给 std::function 对象。
  • Lambda 的好处是它不需要显式的函数声明,可以直接在调用的地方定义。

4. 传递类的成员函数

如果需要传递类的成员函数作为参数,非静态成员函数的传递会稍微复杂一些,因为成员函数需要绑定到对象上。

示例代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

class C {
public:
    int multiply(int a, int b) {
        return a * b;  // 成员函数,计算乘积
    }
};

void invoke(function<int(int, int)> calc) {
    // 调用成员函数
    cout << "Product: " << calc(10, 20) << '\n';
}

int main() {
    C c;  // 创建对象 c
    
    // 使用 bind 绑定成员函数
    auto calc = bind(&C::multiply, &c, placeholders::_1, placeholders::_2);
    
    // 传递绑定的成员函数
    invoke(calc);
    
    return 0;
}

输出:

复制代码
Product: 200

说明:

  • 在 main 函数中,使用 bind 将成员函数 C::multiply 与对象 c 绑定。
  • bind 返回一个可以作为普通函数调用的对象,我们将其传递给 invoke 函数。
相关推荐
陈天伟教授3 分钟前
《数据处理和标注技术》课程能力图谱
人工智能·算法
LMT_Lanmantech6 分钟前
HyperWorks许可:almutil显示Unit满了,数据到底准不准?
运维·服务器·算法
YSL0701247 分钟前
一文通关-----栈和队列
开发语言·数据结构
禁默17 分钟前
论文解读与思考:基于场所地图的标识感知机器人探索方法及工程参考的价值
人工智能·深度学习·算法·机器人
维克兜率天17 分钟前
【维克】统计套利建模:从因子到信号的完整流程
android·开发语言·python·算法·kotlin
Pin_Qing22 分钟前
同一天,谷歌半价卖旗舰,阶跃翻倍收缓存
大数据·开发语言·人工智能·程序人生·缓存
Zentceh24 分钟前
PixelClean 这类 AI 降噪算法是怎么工作的?从 RAW 域到 GAN 色彩重建的技术拆解
图像处理·人工智能·科技·算法·计算机视觉·车载系统·智能硬件
2501_9307077828 分钟前
使用C#代码在 Word 文档中添加、插入或删除页面
开发语言·c#·word
用户03906147071929 分钟前
无感观测器理论模型(NTSM-SMO-PLL 与 SMO-PLL)
算法
没有梦想的咸鱼185-1037-166331 分钟前
从通量数据到SCI论文——AI-R语言生态系统碳水热通量及其机制分析与论文
开发语言·人工智能·数据分析·r语言