C++中的bind实践代码

 更新时间:2025年12月11日 09:20:38   作者:码上睡觉  
std::bind是C++中的一个函数适配器,用于预先固定函数的某些参数,生成一个新的函数对象,它通过占位符来实现参数的占位和重排,本文介绍C++中的bind代码实践,感兴趣的朋友跟随小编一起看看吧

1.std::bind是什么?

简单来说,std::bind 是一个函数适配器(Adapter)

核心作用是“预先固定”一个函数的某些参数,从而生成一个新的函数对象。

你可以把它想象成一个模具:原来的函数需要 3 个原料,你先塞进去 1 个固定的原料,剩下的 2 个留空(占位),这就变成了一个只需要 2 个原料的新工具。

2. 核心机制:占位符 (std::placeholders)

要使用 std::bind,必须先认识它的搭档:占位符

它们位于 std::placeholders 命名空间下,通常写成 _1, _2, _3...

  • _1:代表新函数被调用时的第 1 个参数。
  • _2:代表新函数被调用时的第 2 个参数。
  • 以此类推。

3. 代码实战

我们需要包含头文件:

#include <functional>
using namespace std::placeholders; // 方便使用 _1, _2

场景 A:固定参数(减少参数个数)

假设你有一个减法函数,你希望得到一个“减去 10”的专用函数。

#include <iostream>
#include <functional>
using namespace std::placeholders;
int sub(int a, int b) {
    return a - b;
}
int main() {
    // 使用 bind:
    // 我们把 sub 的第二个参数 b 固定死为 10
    // _1 代表新函数 sub_ten 的第一个参数,它会被填入 sub 的第一个位置 a
    auto sub_ten = std::bind(sub, _1, 10);
    // 调用新函数:
    // 实际执行的是: sub(20, 10)
    std::cout << sub_ten(20) << std::endl; // 输出 10
    return 0;
}

场景 B:参数重排(改变参数顺序)

std::bind 甚至可以颠倒参数的顺序。

// 还是上面的 sub(a, b) -> a - b
// 这次我们交换位置:
// sub 的第一个参数 (a) 吃新函数的第二个参数 (_2)
// sub 的第二个参数 (b) 吃新函数的第一个参数 (_1)
auto reverse_sub = std::bind(sub, _2, _1);
// 调用: reverse_sub(10, 20)
// 实际执行: sub(20, 10) -> 20 - 10
std::cout << reverse_sub(10, 20) << std::endl; // 输出 10

场景 C:绑定成员函数(最常用的旧式写法)

这是 std::bind 在 C++11 初期最常见的用途:配合 std::function 做回调,特别是为了绑定 this 指针。

class Hero {
public:
void heal(int amount) {
    std::cout << "Healed " << amount << " hp." << std::endl;
}
};
int main() {
    Hero myHero;
    // 绑定成员函数
    // 参数1:成员函数指针 &Hero::heal
    // 参数2:对象实例的地址 &myHero (作为隐式的 this)
    // 参数3:占位符 _1 (将来传进来的 amount)
    std::function<void(int)> func = std::bind(&Hero::heal, &myHero, _1);
    func(50); // 输出: Healed 50 hp.
}

4. 这里的坑:参数拷贝 vs 引用

这是 std::bind 最容易出错的地方。std::bind 默认是按值拷贝参数的!

如果你想绑定的参数是一个引用,或者是一个无法拷贝的对象

(比如 unique_ptr),你必须显式使用 std::refstd::cref (const ref)。

void updateScore(int& score, int val) {
    score += val;
}
int main() {
    int myScore = 100;
    // 错误写法!
    // auto update = std::bind(updateScore, myScore, _1); 
    // 这会导致 bind 内部拷贝了一份 myScore,原本的 myScore 不会变。
    // 正确写法:使用 std::ref
    auto update = std::bind(updateScore, std::ref(myScore), _1);
    update(20); 
    std::cout << myScore << std::endl; // 输出 120
}

5. 灵魂拷问:为什么现在不推荐用std::bind?

既然 Lambda 讲完了,Bind 也讲完了,我们对比一下。现在 C++ 社区(包括官方指南)强烈建议能用 Lambda 就别用 Bind

原因如下:

  1. 可读性差bind(func, _2, 10, _1) 这种写法像是猜谜语,你需要脑补参数填空的对应关系。而 Lambda [](int x, int y) { return func(y, 10, x); } 一目了然。
  2. 容易出错:刚才提到的 std::ref 问题,很容易忘记写,导致很多隐晦的 Bug。而 Lambda 的捕获列表 [&] 显式且直观。
  3. 编译器优化:Lambda 表达式对编译器来说是透明的代码块,容易内联优化。std::bind 生成的是复杂的模板对象,编译器优化起来比较费劲,有时会导致生成的二进制代码更大、更慢。

对比示例:

// 任务:调用 object.process(data)
// 方式 1: std::bind (旧时代)
auto task1 = std::bind(&MyClass::process, &object, data);
// 方式 2: Lambda (新时代 - 推荐)
auto task2 = [&object, data]() { object.process(data); };

到此这篇关于C++中的bind代码实践的文章就介绍到这了,更多相关C++ bind内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 带你了解C++中的sort函数

    带你了解C++中的sort函数

    这篇文章主要给大家介绍了关于C++中sort函数的基础入门使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起看看吧
    2021-08-08
  • C语言头文件<string.h>函数详解

    C语言头文件<string.h>函数详解

    本文主要介绍了C语言头文件<string.h>函数详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • C++ primer超详细讲解顺序容器

    C++ primer超详细讲解顺序容器

    本文主要介绍了C++顺序容器(vector、deque、list)的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 简单的汉诺塔问题解法代码

    简单的汉诺塔问题解法代码

    汉诺塔本是C语言开门就学的东西,简单的汉诺塔问题解法代码
    2013-03-03
  • C++ min/max_element 函数用法详解

    C++ min/max_element 函数用法详解

    这篇文章主要介绍了C++ min/max_element 函数用法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • C/C++中使用列表框组件Qt ListWidget

    C/C++中使用列表框组件Qt ListWidget

    本文详细讲解了C/C++中使用列表框组件Qt ListWidget的方法,文中通过示例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • C++ 关于MFC List Control 控件的总结

    C++ 关于MFC List Control 控件的总结

    这篇文章主要介绍了C++ 关于MFC List Control 控件的总结的相关资料,十分的详细,有需要的朋友可以参考下
    2015-06-06
  • C++中的模板类&模板函数

    C++中的模板类&模板函数

    这篇文章主要介绍了C++中的模板类&模板函数用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C++中不能被重载的运算符介绍

    C++中不能被重载的运算符介绍

    其实在C/C++ 里大多数运算符都可以在C++中被重载的。C 的运算符中只有 . 和 ?:(以及 sizeof,技术上可以看作一个运算符)不可以被重载
    2013-10-10
  • C语言的可变参数函数实现详解

    C语言的可变参数函数实现详解

    某些情况下我们希望函数的参数个数可以根据需要确定,因此c语言引入可变参数函数。典型的可变参数函数的例子有printf()、scanf()等,下面我就开始讲解
    2021-08-08

最新评论