std::bind 详解

bind

bind 是C++ 的一个函数, 用来绑定其他函数,用来改造。

1. 普通函数的bind

普通函数可以被绑定,传参。

int add(int x, int y){
    cout << "int add(int, int)" << endl;
    return x+y;
}
以上有一个add普通函数,则,bind 绑定。
    
#include <functional>
using std::bind;
int main(){
    auto f = bind(&add, 5, 9);
    f(); 
    add(5,9);
}

f( ) 和 add(5,9) 是等价的。

2. 成员函数的bind

成员函数的bind 大体上类似普通函数, 但 &类内成员函数, 因此,还须生成一个 类对象。

bind(&Class, &obj, 参数...), &obj 的 & 可省略。

class Example{
	public:
		int add(int x, int y){
			return x+y;
		}
}

int main(){
    Example ex;
    auto f = bind(&Example::add, &ex, 5, 9);
    ex.add(5,9);
    f();
}

3. 占位符

bind 可以实现占位符的效果。using namespace std::placeholders
在 bind 时,不直接传参数,而是采用 _n 的占位符, 相当于改造函数。

auto f = bind(&add, _4, _2); 
//表示,调用 f 时, 至少有 4 个参数,且只有第 4 和第 2 个参数有效,作为 add 的第 1 和第 2 个形参。
f(1,2,3,4,5,6,7);
参数的数量可以 > 4, 但不能 < 所指定的占位符的最大值。

4. 传引用参数

bind 可以传递引用参数,因为bind 默认是值传递。

std::cref, std::ref 使用引用包装器。 cref 是 const reference.

int num = 5;
auto f = bind(&add, std::ref(num), num);
num = 9;
f(); 
//此时,f() == add(9,5); 

5. auto 的真面目

add 的函数类型是 int(int, int)
f 的函数类型是 int()

但是直接以 int() f = bind... 不行, 因为要用一个函数容器来包含。

using std::function

using std::function;
function<int()> f = bind(&add, 5, 9);
auto f = bind(&add, 5, 9);
// auto 就是 function<int()>
// f的类型是 int(),所以 function <int()> 
// 如果是 占位符的话, 则就是有参数的。int(int,int) 了。
function<int(int, int)> f = bind(&add, _1, _3);

6. bind 成员变量

bind 返回的是一个函数,成员变量以函数的返回值形式返回。

所以f 的函数类型是 int( )

class Example{
	public:
		int data;
}

Example ex;
function<int()> f = bind(&Example::data, &ex);

总结:

bind 可以让函数或成员变量改造成其他形式的函数。(函数返回类型不变)

附代码:

/*
 *
 * Copyright (C) 2023-07-23 23:29 zxinlog <zxinlog@126.com>
 *
 */

#include <functional>
#include <iostream>

using std::bind;
using std::cout;
using std::endl;
using std::function;
using namespace std::placeholders;

int add(int x, int y) {
    cout << "int add(int x, int y)" << endl;
    return x + y;
}

class Example {
public:
    int add(int x, int y) {
        cout << "int Example::add(int, int)" << endl;
        return x + y;
    }
    int data = 300;
};

void test0() {
    function<int()> f = bind(&add, 1, 2);
    cout << "f() =  " << f() << endl;

    function<int(int, int, int, int)> f2 = bind(&add, _1, _4);
    cout << "f2() = " << f2(1, 3, 4, 8) << endl;

    Example ex;
    function<int()> f3 = bind(&Example::add, &ex, 5, 9);
    cout << "f3() = " << f3() << endl;

    function<int()> f4 = bind(&Example::data, &ex);
    cout << "f4() = " << f4() << endl;
}

int main(int argc, char* argv[]) {
    test0();
    return 0;
}

posted @   zxinlog  阅读(1436)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示