0Pricing
C++ Academy · 课时

std::bind

将参数绑定到可调用对象

std::bind 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

什么是 std::bind

std::bind 通过固定现有可调用对象的部分参数来创建新的可调用对象。这称为部分应用。

  • 位于 <functional> 中。
  • 返回一种未指定的可调用对象。
#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    auto add10 = std::bind(add, 10, 5);
    std::cout << add10() << '\n';
    return 0;
}

占位符

像 std::placeholders::_1 这样的占位符表示要在调用绑定对象时稍后提供的参数。

#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    using namespace std::placeholders;
    auto add10 = std::bind(add, 10, _1);
    std::cout << add10(7) << '\n';
    return 0;
}

重新排列参数

占位符可以按任意顺序出现,因此您可以交换调用者所提供参数的位置。

#include <iostream>
#include <functional>

int sub(int a, int b) { return a - b; }

int main() {
    using namespace std::placeholders;
    auto flipped = std::bind(sub, _2, _1);
    std::cout << flipped(3, 10) << '\n';
    return 0;
}

绑定多个参数

您可以一次固定多个参数,同时将其他参数保留为占位符。

#include <iostream>
#include <functional>

int volume(int l, int w, int h) { return l * w * h; }

int main() {
    using namespace std::placeholders;
    auto box = std::bind(volume, 2, _1, 5);
    std::cout << box(3) << '\n';
    return 0;
}

存储结果

std::bind 返回的对象可以存储在 std::function 中,从而获得一个具体且有名称的类型。

#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    using namespace std::placeholders;
    std::function<int(int)> add100 = std::bind(add, 100, _1);
    std::cout << add100(1) << '\n';
    return 0;
}

绑定成员函数

通过传递成员指针以及代表 this 的对象或占位符,std::bind 可以将目标设为成员函数。

#include <iostream>
#include <functional>

struct Counter {
    int add(int x) { return value += x; }
    int value = 0;
};

int main() {
    using namespace std::placeholders;
    Counter c;
    auto bump = std::bind(&Counter::add, &c, _1);
    std::cout << bump(5) << ' ' << bump(3) << '\n';
    return 0;
}

按值绑定与按引用绑定

绑定的参数默认会被复制。将参数包装在 std::ref 中即可按引用绑定,从而让更改可见。

#include <iostream>
#include <functional>

void addTo(int& target, int amount) { target += amount; }

int main() {
    using namespace std::placeholders;
    int total = 0;
    auto acc = std::bind(addTo, std::ref(total), _1);
    acc(5);
    acc(10);
    std::cout << total << '\n';
    return 0;
}

在算法中使用绑定的可调用对象

绑定的可调用对象可以在标准算法中充当谓词或操作。

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

bool greaterThan(int x, int limit) { return x > limit; }

int main() {
    using namespace std::placeholders;
    std::vector<int> v = {1, 5, 8, 2, 9};
    auto over4 = std::bind(greaterThan, _1, 4);
    std::cout << std::count_if(v.begin(), v.end(), over4) << '\n';
    return 0;
}

嵌套 bind

绑定表达式可以组合,但这样很快就会变得难以阅读。每个占位符仍然指向最终调用者的参数。

#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }
int times(int a, int b) { return a * b; }

int main() {
    using namespace std::placeholders;
    auto f = std::bind(add, std::bind(times, 2, _1), 3);
    std::cout << f(5) << '\n';
    return 0;
}

忽略额外参数

如果绑定调用只使用了部分占位符,那么调用时传入的任何额外参数都会被直接忽略。

#include <iostream>
#include <functional>

int show(int a) { return a; }

int main() {
    using namespace std::placeholders;
    auto f = std::bind(show, _1);
    std::cout << f(42, 99, 100) << '\n';
    return 0;
}

lambda 表达式更清晰时

现代 C++ 通常更偏好使用 lambda 表达式而不是 std::bind,因为前者更易读,而且编译器可以更好地优化它。

#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    auto add10 = [](int x) { return add(10, x); };
    std::cout << add10(5) << '\n';
    return 0;
}

快速检查

测试您对占位符的理解。

回顾

您学会了 std::bind 的工作方式:

  • 固定部分参数,并使用占位符 _1、_2 表示其余参数
  • 可以重新排列参数、绑定成员函数,以及使用 std::ref
  • 结果可以存储在 std::function 中,并用于算法
  • 在现代 C++ 中,lambda 表达式通常更清晰

接下来,您将比较 lambda 表达式、bind 和函数指针,以选择合适的工具。

常见问题解答

「std::bind」课时是免费的吗?

是的 — 「std::bind」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「std::bind」这节课中我会学到什么?

将参数绑定到可调用对象 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「std::bind」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 函数指针
  2. std::function
  3. std::bind
  4. 选择可调用对象
← 返回 C++ Academy