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 反馈 — 无需本地设置。
此课程中的所有课时
- 函数指针
- std::function
- std::bind
- 选择可调用对象