C++11 bind函数

本文介绍了C++11中的bind函数,它是一个函数适配器,能够接受可调用对象并生成新的可调用对象。bind允许我们预设参数,使用占位符_n指定参数位置。通过举例,解释了如何使用bind来替代Lambda表达式,并展示了如何处理引用参数,特别是当参数不希望被拷贝时,可以使用std::ref。此外,文章还提及了旧的bind1st和bind2nd函数已被弃用,推荐使用更灵活的bind。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:《C++ Primer 第五版》

参数绑定

如果一个函数只在一两个地方操作,使用Lambad很方便,如果在很多地方操作,编写多次相同的Lambda函数就很不方便,需要定义函数。但是,定义的函数又不能完全代替能捕捉局部变量的Lambda函数,所以就出现了bind函数。
bind函数是C++11标准库的函数,需要添加头文件

#include <functional.h>

bind就是一个通用的函数适配器,它可以接受一个可调用函数,生成一个新的可调用对象来“适应”原函数的参数列表。

std::bind函数

调用bind函数的方式为:

auto newCallable = bind(callable, arg_list);

说明:
callable : 本身就是一个可调用的函数
arg_list : 用逗号分割的参数列表,对应给定的callable参数

当我们调用newCallable时,会调用callable函数,并且将arg_list的参数传递给callable函数。

参数占位符

arg_list中有许多占位符,形如_n的名字,其中n是一个整数,表示newCallable的参数的位置比如:_1为newCallable的第一个参数,_2为第二个参数…。

举例说明:
现在有一个函数:

bool checkSize(const string &s, string::size_type sz)
{
    return s.size() >= sz;
}

使用bind生成一个调用checkSize的对象:

auto check = bind(checkSize, _1, 6);

其中的_1表示需要给第一个参数传递一个const string&。

string s = "hello";
bool b1 = check(s); //check(s) 会调用checkSize(s, 6)

使用bind,可以将原来的基于Lambda的find_if调用:

auto wc = find_if(words.begin(), words.end(), [sz](const string &a));

改变为使用checkSize版本:

auto wc = find_if(words.begin(), words.end(), bind(check_size, _1, sz));

_n参数说明

_n参数都定义在一个名字为placeholders命名空间中,这个命名空间又在std命名空间中。那么_1就是:

using std::placeholders::_1;

对每一个占位符都要使用using声明,非常麻烦,可以使用:

using namespace std::placeholders;

placeholders的明明空间也定义在functional.h头文件中

bind的参数顺序

bind绑定的给定函数的参数的顺序。比如func是一个函数,它有5个参数,下面对bind的调用:

auto g = bind(fun, a, b, _2, c, _1);

生成一个新的可调用对象,有两个占位符,传递给g的第一个参数绑定到_1,第二个参数绑定到_2,bind调用会将g(_1, _2)映射为f(a, b, _2, c, _1),如:调用g(X, Y)就会调用f(a, b, Y, c, X);

绑定引用参数

默认情况下,bind的非占位符的参数是拷贝到bind返回的可调用的函数中,与Lambda类似,有时候绑定的参数希望用引用的方式传递,或不让绑定的参数类型拷贝。
例如:

for_each(words.begin(), words.end(), [&os, c](const string &s) {os << s << c;});

可以编写一个函数完成同样的功能:

ostream &print(ostream &os, const strint &s, char c)
{
    return os << s << c;
}

但是:不能直接用bind来代替os的捕获:

for_each(words.begin(), words.end(), bind(print, os, _1, ' ');

由于不能拷贝一个ostream。如果我们希望bind一个函数而不希望拷贝参数,就需要用标准库的ref函数。

for_each(words.begin(), words.end(), bind(printf, ref(os), _1, ' '));

函数ref返回一个对象,包含给定的引用,此对象是可以拷贝的。标准库中还有cref函数,生成一个保存const引用的类。ref和cref都在头文件"functional.h"

关于bind1st和bind2nd函数

标准库中定义了这两个函数,类似于bind,但是这两个函数只能分别绑定第一个或第二个参数。由于局限性太强,在C++11中已经被弃用,新的C++应该使用bind。

### 回答1: C 语言中的 bind 函数是指将一个套接字和特定的 IP 地址和端口号绑定在一起。它通常在服务器端程序中使用,用来指定服务器的地址和端口号,以便客户端程序能够连接到服务器。 语法: ``` int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); ``` 其中,sockfd 是指要绑定的套接字的文件描述符;addr 是一个指向 sockaddr 结构体的指针,其中包含了要绑定的 IP 地址和端口号;addrlen 是 sockaddr 结构体的大小。 返回值: - 成功时返回 0; - 失败时返回 -1,并设置 errno。 示例代码: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 12345 int main(void) { int sockfd; struct sockaddr_in server_addr; // 创建套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 设置服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); // 绑定套接字 if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); close(sockfd); exit(EXIT_FAILURE); } // 其他代码 close ### 回答2: C语言中的bind函数是一个网络编程函数,用于将套接字(socket)与特定的IP地址和端口号绑定在一起。它是在Linux系统的socket库中提供的一个函数bind函数的原型如下: #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 其中,sockfd是套接字描述符,addr是指向特定IP地址和端口号的结构体指针,addrlen表示addr结构体的大小。 bind函数的作用是将指定的套接字与特定的IP地址和端口号进行绑定。它通常用于服务器程序,在服务器程序中,我们需要先创建一个套接字,并调用bind函数将套接字与服务器所在的IP地址和端口号绑定,从而使得其他计算机可以通过这个IP地址和端口号来访问服务器。 使用bind函数时,我们需要先创建一个套接字,然后使用bind函数指定套接字需要绑定的IP地址和端口号。如果绑定成功,bind函数返回0;如果出现错误,返回-1,并设置errno来指示错误类型,可以使用perror函数打印错误信息。 bind函数在网络编程中是非常常用的,它是建立服务器程序的第一步。通过绑定特定的IP地址和端口号,我们可以使得服务器可以监听来自网络上其他计算机的请求,并与其进行通信。 ### 回答3: bind函数C++标准库中的一个函数,用于将函数对象与其参数进行绑定,从而生成一个新的可调用对象。 bind函数的使用方式比较灵活。它可以将一个函数对象与零个或多个参数进行绑定,也可以将成员函数与其对应的对象进行绑定。 bind函数的语法如下: template< class F, class... Args > bind( F&& f, Args&&... args ); 其中,F是函数类型,args是需要绑定的参数。 使用bind函数的步骤为: 1. 创建需要绑定的函数对象,可以是普通函数函数指针、成员函数指针等。 2. 将函数对象传递给bind函数,同时将需要绑定的参数也传递给bind函数。 3. bind函数会返回一个新的可调用对象,可以使用这个对象进行函数调用。 bind函数的返回值类型是一个可调用对象,因此可以直接对其进行调用操作。该对象会自动根据绑定的参数类型进行调用。 使用bind函数可以实现一些方便的功能,比如: 1. 将多参数函数转换为单参数函数。 2. 固定函数的部分参数,从而生成一个新的可调用对象。 3. 将成员函数绑定到对象,从而可以在不同的地方调用该成员函数。 总之,bind函数是一个非常有用的函数,能够简化函数的调用过程,提高代码的可读性和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值