c++11之std::bind简单使用
note
- 更多用法,请参考: cppreference
- 用的少,容易忘。
我的理解
- 类似延迟计算。 比如,回调函数,将回调函数传入后,回调函数不一定马上被调用。
- 它是一个模板类,调用后将生成一个新的调用对象A。调用该对象A与调用原函数是等价的。
声明
截至目前,它的声明如下
需要包含头文件
#include <functional>
一个例子
代码
下面的print函数负责输出参数的值, 通过使用std::bind, 生成一个新的对象 func, 此时, func(a, b, c);与print(a, b, c);**的调用结果是等价的。
#include <functional>
void print(int a, int b, int c)
{
std::cout << "a = " << a << ", b=" << b << ", c=" << c << "\n\n";
}
int main(int argc, char* argv[], char* env[])
{
auto func = std::bind(print, std::placeholders::_2, 2, std::placeholders::_1);
func(3, 4);
return 0;
}
std::placeholders 说明
std::placeholders::_2和std::placeholders::_1表示参数的顺序,比如, 上面的代码示例中, 3是func的第一个参数,但是,func在声明时,指定了第一个参数的位置,放在了最后。 所以,上面的代码输出结果: a=4, b=2, c=3。
注意
- std::bind的函数参数默认使用的是拷贝, 如果需要使用引用,则需要配合std::ref。
- 下面一个例子,帮助理解。
print2函数负责输出参数的值,且参数都是引用, print2函数内完成对参数的自增
#include <functional>
void print2(int &a, int &b)
{
std::cout << "函数调用:a=" << a << ", b=" << b << "\n";
++a;
++b;
}
int main(int argc, char* argv[], char* env[])
{
int a = 1;
int b = 2;
auto func2 = std::bind(print2, a, std::ref(b));
std::cout << "调用前,a=" << a << ", b=" << b << "\n";
func2();
std::cout << "调用后,a=" << a << ", b=" << b << "\n";
return 0;
}
调用时,尽管都采用了传入引用的方式,但略有不同。参数a使用的是传统的方式,参数b采用的是 std::ref的方式。 观察输出结果
可以看到,std::bind的参数是以 拷贝的方式,使用 std::ref 的方式可以实现参数在std::bind的引用。
官方的例子
#include <random>
#include <iostream>
#include <memory>
#include <functional>
void f(int n1, int n2, int n3, const int& n4, int n5)
{
std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
int g(int n1)
{
return n1;
}
struct Foo {
void print_sum(int n1, int n2)
{
std::cout << n1+n2 << '\n';
}
int data = 10;
};
int main()
{
using namespace std::placeholders; // for _1, _2, _3...
// demonstrates argument reordering and pass-by-reference
int n = 7;
// (_1 and _2 are from std::placeholders, and represent future
// arguments that will be passed to f1)
auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
n = 10;
f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
// makes a call to f(2, 42, 1, n, 7)
// nested bind subexpressions share the placeholders
auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
// common use case: binding a RNG with a distribution
std::default_random_engine e;
std::uniform_int_distribution<> d(0, 10);
auto rnd = std::bind(d, e); // a copy of e is stored in rnd
for(int n=0; n<10; ++n)
std::cout << rnd() << ' ';
std::cout << '\n';
// bind to a pointer to member function
Foo foo;
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
f3(5);
// bind to a pointer to data member
auto f4 = std::bind(&Foo::data, _1);
std::cout << f4(foo) << '\n';
// smart pointers can be used to call members of the referenced objects, too
std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
<< f4(std::make_unique<Foo>(foo)) << '\n';
}
官方例子输出
2 42 1 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10
c++11之std::bind简单使用的更多相关文章
- C++11中std::bind的使用
std::bind: Each argument may either be bound to a value or be a placeholder: (1).If bound to a value ...
- 第11课 std::bind和std::function(2)_std::bind绑定器
1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...
- std::bind技术内幕
引子 最近群里比较热闹,大家都在山寨c++11的std::bind,三位童孩分别实现了自己的bind,代码分别在这里: 木头云的实现 mr.li的实现 null的实现,null的另一个版本的实现 这些 ...
- std::bind与std::ref, why and how
首先解释下为什么有时候需要bind. 我们可以用bind从函数T add(T a, T b)造出个inc()来,即把b写死为1.这个例子本身比较傻,但有不傻的应用. template<typen ...
- C++11多线程std::thread的简单使用
在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上.但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有 ...
- C++11中提供了std::bind
再来看看std::bind C++11中提供了std::bind.bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的. bind的思想实际上是一种延迟计算的思想,将可调用对象保存 ...
- c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind
一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...
- C++11之std::function和std::bind
std::function是可调用对象的包装器,它最重要的功能是实现延时调用: #include "stdafx.h" #include<iostream>// std ...
- [C/C++11]_[初级]_[std::bind介绍和使用]
场景 1.C++11 引入了std::function 对象, 这个对象可以通过std::bind封装所有的函数, 并通过代理调用这个std::function的方式调用这个函数. 比如通过统一的方式 ...
随机推荐
- CSP-S 2021 游记
福兮祸之所伏 胜利是一种肯定,代表我应该在这条路上坚定不移地走下去. 胜利也是一种危机,它粉饰太平.养虎自齧,并把人最丑陋的一些想法暴露出来:虚荣心.骄傲心都在这个过程中被放大,懒惰心.自满心也找到了 ...
- 记一次VS2010和VS2015自定义颜色的过程
首先,是遇到的问题: 一天,使用VS2010看新项目代码时候,发现选中某个变量后,其它位置高亮显示的变量颜色太淡,不利于阅读代码,如下图.所以想修改这个颜色. 后来网上找了一遍,可以这样设置:工具-- ...
- 搭建简单的SpringCloud项目三:问题及解决
GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 搭建简单的SpringCloud项目二:服务 ...
- 基于 Golang 构建高可扩展的云原生 PaaS(附 PPT 下载)
作者|刘浩杨 来源|尔达 Erda 公众号 本文整理自刘浩杨在 GopherChina 2021 北京站主会场的演讲,微信添加:Erda202106,联系小助手即可获取讲师 PPT. 前言 当今时 ...
- STL全特化与偏特化
在泛型编程中,常常会使用一些非完全泛型的类模板,这就是特化. 如何理解全特化呢?如上图所示,第一个template class是空间配置器的类模板,第二个就是一个全特化的template class. ...
- Linux基础命令---httpd守护进程
httpd httpd是apache超文本传输协议的主程序,它被设计成一个独立运行的守护进程.httpd会建立一个线程池来处理http请求. 此命令的适用范围:RedHat.RHEL.Ubuntu.C ...
- Linux后台启动服务
systemctl 启动/关闭/启用/禁用服务 总结 启动服务 systemctl start test.service 关闭服务 systemctl stop test.service 重启服务 s ...
- 3.1 go context代码示例
context.WithCancel返回两个有关联的对象,ctx与cancel,调用cancel发送一个空struct给ctx,ctx一旦接收到该对象后,就终止goroutine的执行;ctx是线程安 ...
- 【C/C++】函数的默认参数/函数的占位参数/函数重载/注意事项
函数的默认参数 返回值类型 函数名(参数=默认值){} #include <iostream> using namespace std; int func(int a = 10, int ...
- SVM中的软间隔最大化与硬间隔最大化
参考文献:https://blog.csdn.net/Dominic_S/article/details/83002153 1.硬间隔最大化 对于以上的KKT条件可以看出,对于任意的训练样本总有ai= ...