博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ Primer Plus 学习笔记 第十八章 lambad 匿名函数, 包装器
阅读量:4126 次
发布时间:2019-05-25

本文共 4914 字,大约阅读时间需要 16 分钟。

没有函数名的函数

格式

程序示例

#include 
#include
#include
#include
#include
const long Size1 = 39L;const long Size2 = 100*Size1;const long Size3 = 100*Size2;bool f3(int x) {return x % 3 == 0;}bool f13(int x) {return x % 13 == 0;}int main(){ using std::cout; std::vector
number(Size1); std::srand(std::time(0)); std::generate(number.begin(), number.end(), std::rand); cout << "Sample size = " << Size1 << '\n'; int count3 = std::count_if(number.begin(), number.end(), f3); cout << "Count of number divisible by 3: " << count3 << '\n'; int count13 = std::count_if(number.begin(), number.end(), f13); cout << "Count of numbers divisible by 13:" << count13 << "\n\n";// 改变容器大小 比原来的大,如果没有第二个参数做指定值,就按默认值填充,如果比原来小。超出部分直接砍掉 number.resize(Size2); // 通过随机函数填充容器 std::generate(number.begin(), number.end(), std::rand); cout << "Sample size = " << Size2 << '\n'; class f_mod { private: int dv; public: f_mod(int d = 1) : dv(d){} bool operator()(int x) {return x % dv == 0;} }; count3 = std::count_if(number.begin(), number.end(), f_mod(3)); cout << "Count of numbers divisible by 3: " << count3 << '\n'; count13 = std::count_if(number.begin(), number.end(), f_mod(13)); cout << "Count of numbers divisible by 13: " << count13 << "\n\n"; number.resize(Size3); count3 = std::count_if(number.begin(), number.end(), [](int x){return x % 3 == 0;}); cout << "Count of numbers divisible by 3: " << count3 << '\n'; count13 = std::count_if(number.begin(), number.end(), [](int x){return x % 13 == 0;}); cout << "Count of numbers divisible by 13: " << count13 << "\n\n"; return 0;}

最后为毛是乱码还不知道 试了好多次都不行

lambda的额外功能

能够访问作用域内的任何动态变量

将要捕获的变量放到中括号中

程序示例

#include 
#include
#include
#include
#include
const long Size = 39000L;int main(){ using std::cout; std::vector
numbers(Size); std::srand(std::time(0)); std::generate(numbers.begin(), numbers.end(), std::rand); cout << "Sample size = " << Size << '\n'; int count3 = std::count_if(numbers.begin(), numbers.end(), [](int x) {return x % 3 == 0;}); cout << "Count of numbers divisible by 3: " << count3 << '\n'; int count13 = 0; std::for_each(numbers.begin(), numbers.end(), [&count13] (int x) {count13 += x % 13 == 0;}); cout << "Count of numbers divisible by 13: " << count13 << "\n\n";//使用匿名函数传调用动态变量 count3 = count13 = 0; std::for_each(numbers.begin(), numbers.end(), [&](int x) {count3 += x % 3 == 0; count13 += x % 13 == 0;}); cout << "Count of numbers divisible by 3: " << count3 << '\n'; cout << "Count of numbers divisible by 13: " << count13 << "\n\n"; return 0;}

 

包装器(wrapper)

也叫适配器(adapter)

给其他编程接口提供更一致或更合适的接口。类似转接器(转接头一样的功能)

包装器模板:

bind,, men_fn,reference_wrapper和function

模板函数决定要不要重新实例化还是使用现有的已经实例化的模板函数的判断依据

看参数的数据类型,如果参数是函数就看该函数传入的参数类型和返回类型是否一致

程序示例

//somedefs.h#include 
template
T use_f(T v, F f){ static int count = 0; count++; std::cout << " use_f count = " << count << ", &count = " << &count << std::endl; return f(v);}class Fp{ private: double z_; public: Fp(double z = 1.0) : z_(z) {} double operator()(double p) {return z_*p;}};class Fq { private: double z_; public: Fq(double z = 1.0) :z_(z){} double operator()(double q) {return z_+ q;}};
//callable.cpp#include 
#include "somedefs.h"double dub(double x) {return 2.0*x;}double square(double x) {return x*x;}int main(){ using std::cout; using std::endl; double y = 1.21; cout << "Function pointer dub:\n"; cout << " " << use_f(y, dub) << endl; cout << "Function pointer square:\n"; cout << " " << use_f(y, square) << endl; cout << "Function object Fp:\n"; cout << " " << use_f(y, Fp(5.0)) << endl; cout << "Function object Fq:\n"; cout << " " << use_f(y, Fq(5.0)) << endl; cout << "Lambda expression 1:\n"; cout << " " << use_f(y, [](double u) {return u*u;}) << endl; cout << "Lambda expression 2:\n"; cout << " " << use_f(y, [](double u) {return u+u/2.0;}) << endl; return 0;}

运行结果(注意调用dub和square)所造成的的实例化被调用了两次。 原因是这两函数 都是传入double类型数据 返回double数据,编译器判断他们是一样的所以调用相同的实例化模板函数

但是不对呀 这几个对象,函数或者函数符什么的  他们都是传入double然后返回double类型的 能不能让他只用1个实例呢?

当然是有啦

先发个理论知识

解决这个问题的办法就是使用模板function包装器

格式

std::function<double(char, int)> fdci;

程序示例

// wrapped.cpp#include 
template
T use_f(T v, F f){ static int count = 0; count++; std::cout << " use_f count = " << count << ", &count = " << &count << std::endl; return f(v);}class Fp{ private: double z_; public: Fp(double z = 1.0) : z_(z) {} double operator()(double p) {return z_*p;}};class Fq { private: double z_; public: Fq(double z = 1.0) :z_(z){} double operator()(double q) {return z_+ q;}};

运行结果: 使用了function模板包装器之后 函数模板就认为是同一个类型传递进来。所以就只调用1个实例化的模板了

这就是包装器(转换器)

但是建6个包装器也蛋疼呀 能不能就建1个

可以呀 有两种方法

第一种 使用临时包装器放置在use_f函数中

第二种方法,直接将包装器放置到模板函数中

完结

转载地址:http://lsepi.baihongyu.com/

你可能感兴趣的文章
Count and Say
查看>>
Gas Station
查看>>
Palindrome Partitioning --回文切割 深搜(重重)
查看>>
Valid Palindrome 简单的回文判断
查看>>
Pascal's Triangle -- 生成杨辉三角
查看>>
Pascal's Triangle II 生成杨辉三角中的某行
查看>>
Minimum Depth of Binary Tree -- 二叉树的最小深度 DFS 加剪枝
查看>>
Climbing Stairs 爬楼梯方法 动态规划
查看>>
Merge Two Sorted Lists 合并两个有序链表
查看>>
pow(x,n) 为什么错这么多次
查看>>
Jump Game 动态规划
查看>>
Subsets 深搜
查看>>
Subsets II
查看>>
Edit Distance 字符串距离(重重)
查看>>
Gray Code 格雷码
查看>>
对话周鸿袆:从程序员创业谈起
查看>>
web.py 0.3 新手指南 - 如何用Gmail发送邮件
查看>>
web.py 0.3 新手指南 - RESTful doctesting using app.request
查看>>
web.py 0.3 新手指南 - 使用db.query进行高级数据库查询
查看>>
web.py 0.3 新手指南 - 多数据库使用
查看>>