C++11新特性应用--实现延时求值(std::function和std::bind)
说是延时求值,注意还是想搞一搞std::function和std::bind。
之前博客《C++11新特性之std::function》注意是std::function怎样实现回调函数。
如今就算是补充吧,再把std::bind进行讨论讨论。
何为Callable Objects?
就可以调用对象,比方函数指针、仿函数、类成员函数指针等都可称为可调用对象。
对象包装器
Function wrapper
Class that can wrap any kind of callable element (such as functions and function objects) into a copyable object, and whose type depends solely on its call signature (and not on the callable element type itself).
An object of a function class instantiation can wrap any of the following kinds of callable objects: a function, a function pointer, a pointer to member, or any kind of function object (i.e., an object whose class defines operator(), including closures).
A decay copy of the wrapped callable object is stored internally by the object, which becomes the function’s target. The specific type of this target callable object is not needed in order to instantiate the function wrapper class; only its call signature.
以下用一段代码:
#include<iostream>
#include<functional>
//普通函数
void func(void)
{
std::cout << "1" << std::endl;
}
//类的成员函数
class A
{
public:
static int A_func(int a)
{
std::cout << "2" << "(" << a << ")" << std::endl;
return a;
}
};
//仿函数
class B
{
public:
int operator()(int a)
{
std::cout << "2" << "(" << a << ")" << std::endl;
return a;
}
};
int main()
{
std::function<void(void)> fun1 = func;
fun1();
std::function<int(int)> fun2 = A::A_func;
std::cout << fun2(123) << std::endl;
B b;
fun2 = b;
std::cout << fun2(123) << std::endl;
return 0;
}
//输出:
1
2(123)
123
2(123)
123
接下来std::function用于回调就不浪费篇幅了,接下来注意分析std::bind。
何为std::bind?
字面意思。绑定器。
simple
template
#include <iostream> // std::cout
#include <functional> // std::bind
// a function: (also works with function object: std::divides<double> my_divide;)
double my_divide(double x, double y) { return x / y; }
struct MyPair {
double a, b;
double multiply() { return a*b; }
};
int main() {
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
// binding functions:
auto fn_five = std::bind(my_divide, 10, 2); // returns 10/2
std::cout << fn_five() << '\n'; // 5
auto fn_half = std::bind(my_divide, _1, 2); // returns x/2
std::cout << fn_half(10) << '\n'; // 5
auto fn_invert = std::bind(my_divide, _2, _1); // returns y/x
std::cout << fn_invert(10, 2) << '\n'; // 0.2
auto fn_rounding = std::bind<int>(my_divide, _1, _2); // returns int(x/y)
std::cout << fn_rounding(10, 3) << '\n'; // 3
MyPair ten_two{ 10,2 };
// binding members:
// returns x.multiply()
auto bound_member_fn = std::bind(&MyPair::multiply, _1);
std::cout << bound_member_fn(ten_two) << '\n'; // 20
// returns ten_two.a
auto bound_member_data = std::bind(&MyPair::a, ten_two);
std::cout << bound_member_data() << '\n'; // 10
return 0;
}
_ 1中的 _ 表示的是占位符,由using namespace std::placeholders; 提供。详细的话找机会再研究。
主要看看上面的代码。bind的几种使用方式。
能够看到。能够绑定所有參数,也能够绑定部分參数。
你可能已经感到bind的威力了吧,那不是重点。与function的结合才是重要的:
//#include <iostream> // std::cout
//#include <functional> // std::bind
//
//// a function: (also works with function object: std::divides<double> my_divide;)
//double my_divide(double x, double y) { return x / y; }
//
//struct MyPair {
// double a, b;
// double multiply() { return a*b; }
//};
//
//int main() {
// using namespace std::placeholders; // adds visibility of _1, _2, _3,...
//
// // binding functions:
// auto fn_five = std::bind(my_divide, 10, 2); // returns 10/2
// std::cout << fn_five() << '\n'; // 5
//
// auto fn_half = std::bind(my_divide, _1, 2); // returns x/2
// std::cout << fn_half(10) << '\n'; // 5
//
// auto fn_invert = std::bind(my_divide, _2, _1); // returns y/x
// std::cout << fn_invert(10, 2) << '\n'; // 0.2
//
// auto fn_rounding = std::bind<int>(my_divide, _1, _2); // returns int(x/y)
// std::cout << fn_rounding(10, 3) << '\n'; // 3
//
// MyPair ten_two{ 10,2 };
//
// // binding members:
// auto bound_member_fn = std::bind(&MyPair::multiply, _1); // returns x.multiply()
// std::cout << bound_member_fn(ten_two) << '\n'; // 20
//
// auto bound_member_data = std::bind(&MyPair::a, ten_two); // returns ten_two.a
// std::cout << bound_member_data() << '\n'; // 10
//
// return 0;
//}
#include<iostream>
#include<functional>
class A {
public:
int i_ = 0;
void output(int x, int y)
{
std::cout << x << " " << y << std::endl;
}
};
int main()
{
A a;
std::function<void(int, int)> func1 = std::bind(&A::output, &a, std::placeholders::_1,
std::placeholders::_2);
func1(1, 2);
std::function<int&(void)> func2 = std::bind(&A::i_, &a);
func2() = 888;
std::cout << a.i_ << std::endl;
return 0;
}
//输出:
1 2
888
C++11新特性应用--实现延时求值(std::function和std::bind)的更多相关文章
- C++11新特性(1) 右值引用
在C++中,左值(lvalue)是能够获取其地址的一个量.因为常常出如今赋值语句的左边.因此称之为左值.比如一个有名称的变量. 比如: int a=10; //a就是一个左值. 传统的C++引用,都是 ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- C++11新特性总结 (二)
1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...
- C++11新特性总结 (一)
1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...
- C++ 11 新特性
C++11新特性: 1.auto 2.nullptr 3.for 4.lambda表达式 5.override ...
- 在C++98基础上学习C++11新特性
自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...
- C++11新特性——range for
很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ...
- C++11新特性——大括号初始化
C++11之前,C++主要有以下几种初始化方式: //小括号初始化 string str("hello"); //等号初始化 string str="hello" ...
随机推荐
- js代码从页面移植到文件里失效或js代码改动后不起作用的解决的方法
近期在做关于站点的项目,总是发生这种问题 写的javascript代码在页面上没有问题,可是将js代码移植到.js的文件里,在页面上进行调用,总是出现失效等错误 另外改动后的js代码,又一次刷新网页仍 ...
- Apache Pig的前世今生
近期,散仙用了几周的Pig来处理分析我们站点搜索的日志数据,感觉用起来非常不错,今天就写篇笔记介绍下Pig的由来,除了搞大数据的人,可能非常少有人知道Pig是干啥的.包含一些是搞编程的,但不是搞大数据 ...
- kentico中的page template的使用
父页面使用自己的template 子页面,也使用自己的template. 然后父页面中需要添加一个place holder. 子页面的继承,选择inherit only master page. 这样 ...
- Maven + SpringMVC + Mybatis
使用IDEA配置Maven + SpringMVC + Mybatis [一步一步踩坑详细配置完成] PS:初学,想使用Maven配置一个SpringMVC的开发环境,照着网上的各种图文解说,配置了好 ...
- 院校-美国:哈佛大学(Harvard University)
ylbtech-院校-美国:哈佛大学(Harvard University) 哈佛大学(Harvard University),简称“哈佛”,坐落于美国马萨诸塞州波士顿都市区剑桥市,是一所享誉世界的私 ...
- 函数与装饰器Python学习(三)
1.1 文件处理 1.1.1 打开文件过程 在Python中,打开文件,得到文件句柄并赋值给一个变量,默认打开模式就为r f=open(r'a.txt','w',encoding='utf-8') p ...
- Oracle学习笔记——常用函数总结
在平时写PL/SQL的时候,经常要用到很多系统自带的函数,而这些函数用起来非常好用,但是每次用完以后,就又忘到脑后了,为了加深自己的映象,以及对这些函数做一个全面的总结,就有了今天这篇文章. 首先这就 ...
- Kattis -Backspace
Backspace Bjarki having trouble Shortly before the programming contest started, Bjarki decided to up ...
- 学习SCSS
目录 变量 嵌套 引入 混合 继承 操作符 CSS扩展 嵌套属性 标签(空格分隔): 未分类 变量 变量用来存储需要在CSS中复用的信息,例如颜色和字体.SASS通过$符号去声明一个变量. $font ...
- poj 2954 Triangle 三角形内的整点数
poj 2954 Triangle 题意 给出一个三角形的三个点,问三角形内部有多少个整点. 解法 pick's law 一个多边形如果每个顶点都由整点构成,该多边形的面积为\(S\),该多边形边上的 ...