当前位置:首页 > 技术分析 > 正文内容

std::function | std::bind | lambda

ruisui884周前 (05-23)技术分析18

c++ 使用中经常遇到函数对象、函数指针、匿名函数、参数绑定等概念,初次接触总是晕乎乎的,因此本文系统整理下他们的区别、用法。

--1 std::function

泛型函数封装器、用于存储和调用可调用对象。是不是很像函数指针的用途,其实它和函数指针的功能基本一致,只是它能支持lambda 表达式、成员函数的封装和调用,因此通用性更强。

函数指针表达式:					返回类型 (*指针名)(参数类型列表);
std::function 表达式:	std::function<返回类型(参数类型列表)>函数名

可以发现,它和lambda 和 std::bind的关系是,lambda 表达式和 std::bind 的返回值可以用std::function 去封装。

#include <iostream>
#include <functional>

int main() {
    int value = 42;
    auto lambda = [value] { return value; };

    // 将 Lambda 表达式封装到 std::function 中
    std::function<int()> func = lambda;

    // 通过 std::function 调用 Lambda 表达式
    int result = func();
    std::cout << "Result: " << result << std::endl; // 输出 "Result: 42"

    return 0;
}
#include <iostream>
#include <functional>

// 普通函数
void printMessage(const std::string& message, int repeat) {
    for (int i = 0; i < repeat; ++i) {
        std::cout << message << std::endl;
    }
}

int main() {
    // 使用 std::bind 绑定参数
    auto boundFunction = std::bind(printMessage, "Hello", std::placeholders::_1);

    // 将绑定表达式封装到 std::function 中
    std::function<void(int)> func = boundFunction;

    // 通过 std::function 调用绑定表达式
    func(3); // 输出 "Hello" 三次

    return 0;
}

--2 std::bind

表达式:std::bind(可调用对象, 参数列表...)

std::bind 是c++ 标准库中的一个函数模板,用于创建一个可调用对象,他可以将一个函数或者可调用对象的参数绑定为固定值(当绑定成员函数的时候,第一个参数可以认为是将该成员函数的this指针绑定为固定值)。

--2.1 绑定普通函数

#include <iostream>
#include <functional>

void print(int a, int b) {
    std::cout << a << ", " << b << std::endl;
}

int main() {
    auto bound_func = std::bind(print, 10, std::placeholders::_1); // 将第一个参数绑定为 10
    bound_func(20); // 输出:10, 20
    return 0;
}

--2.2 绑定成员函数

#include <iostream>
#include <functional>

class MyClass {
public:
    void print(int a, int b) {
        std::cout << a << ", " << b << std::endl;
    }
};

int main() {
    MyClass obj;
    auto bound_member_func = std::bind(&MyClass::print, &obj, std::placeholders::_1, std::placeholders::_2);
    bound_member_func(10, 20); // 输出:10, 20
    return 0;
}

--2.3 绑定lambda表达式

#include <iostream>
#include <functional>

int main() {
    auto lambda = [](int a, int b) {
        std::cout << a << ", " << b << std::endl;
    };

    auto bound_lambda = std::bind(lambda, 10, std::placeholders::_1);
    bound_lambda(20); // 输出:10, 20
    return 0;
}

--3 lambda

用于在代码中直接定义简短的函数,捕获当前作用域的变量,语法简洁,性能更好。

[capture-list] (parameters) -> return-type { body }
#include <iostream>
#include <functional>

class MyClass {
public:
    void printMessage(const std::string& message) {
        std::cout << "Message: " << message << std::endl;
    }
};

int main() {
    MyClass obj;
    auto lambda = [&obj](const std::string& message) { obj.printMessage(message); };
    lambda("Hello from Lambda!");
    return 0;
} 

上面的例子有两个疑问?

(1)&obj 是取址吗?那传入的是指针吗?

(2)如果是指针那为什么不是 obj ->printMessage(message); ?

原因是:这里的&代表的捕获引用,而不是取地址,函数体内是obj是外部obj传入的别名对象,不是指针。

这里也可以是[&](const std::string& message) { obj.printMessage(message); }这个写法,代表捕获当前作用域中所有外部变量的引用。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/4271.html

标签: bindmessage
分享给朋友:

“std::function | std::bind | lambda” 的相关文章

7种超轻量级的Linux发行版,能够帮助你找到适合自己的操作系统

Linux是一种非常受欢迎的开源操作系统,而且有许多版本可以选择。有时候,你需要一种超轻量级的Linux发行版,它可以在资源有限的设备上运行,并且能够快速启动。本文将介绍7种超轻量级的Linux发行版,希望能够帮助你找到适合自己的操作系统。1. Tiny Core LinuxTiny Core Li...

vue中组件之间的通信方式

** 1.1 父子组件**a. 父向子传数据: 第1种: 父通过属性传值,子组件通过props接收数据(注:props传过来的数据是单向的,不可以进行修改)第2种:子组件可以通过$parent来获取父组件里的数据和调用父组件的方法(注:数据是双向的,还要注意如用了UI组件并且在该UI组件里重新定义一...

基于gitlab的PR操作教程

基于gitlab的PR操作教程注:该教程主要基于git命令行操作,其他图形化工具也可完成以下所有操作步骤,顺手即可。推荐工具:Source Tree ,TortoiseGit参考:gitflow一 . 基于分支的PR操作1. 本地切换到master分支1. 拉取最新代码2. 基于master创建ho...

jvm疯狂吃内存,到底是谁的锅?

jvm应该是每一个java程序员都需要掌握的内容,但是在没有遇到问题之前,很多都是基于理论的,唯有实战才能增加个人的知识储备。本文是从一个角度来分析是谁在狂吃内存,希望对你有所帮助。本文是易观技术人员注意到一台开发机上各个微服务进程占用内存很高,随即便展开了调查......ps:本文来源于:http...

vue v-html动态生成的html怎么加样式/事件

1、动态生成的html,样式不生效//html 布局 <view v-html="html"> {{html}} </view> //动态生成的元素 <view class="btngo" @tap="handleLink...

多项修正 尼康D4s发布最新1.10版固件

尼康公司与2014年8月27日发布了D4s的最新固件,固件版本号为C:1.10。这次固件升级,主要解决了一些BUG,并且对拍摄菜单与相机操作做了一定调整。下面是本次新固件的具体信息:尼康发布D4s最新C固件 1.10版对C固件升级到1.10版所作的修改:当选定运动VR模式并换上 AF-S 尼克尔 4...