当前位置: 首页 > news >正文

北海做网站网站建设查询网 域名查询

北海做网站网站建设,查询网 域名查询,做网站手机端不做PC可以吗,电子商务网站设计与建设目录 前言一,可变参数模板1.1 简单认识1.2 STL容器中的empalce系列相关接口 二,lambda表达式2.1 lambda表达式语法2.2 探索lambda底层 三,包装器3.1 function包装器3.2 bind 四,类的新功能4.1 默认成员函数4.2 关键字default4.3 关…

目录

  • 前言
  • 一,可变参数模板
    • 1.1 简单认识
    • 1.2 STL容器中的empalce系列相关接口
  • 二,lambda表达式
    • 2.1 lambda表达式语法
    • 2.2 探索lambda底层
  • 三,包装器
    • 3.1 function包装器
    • 3.2 bind
  • 四,类的新功能
    • 4.1 默认成员函数
    • 4.2 关键字default
    • 4.3 关键字delete

点击跳转上一篇文章: 【C++11】:右值引用&移动语义&完美转发

前言

上篇文章我们学习了右值引用,那是C++11中新语法的重难点。本篇文章继续学习另外两个新语法:lambda表达式&function包装器。这两个语法在以后的学习和工作中也是经常使用的,所以要重点掌握,而它们的铺垫知识可变参数模板只需略作了解即可。

一,可变参数模板

1.1 简单认识

功能:可以接受可变参数的函数模板和类模板

下面就是一个基本可变参数的函数模板:

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}

上面的参数args前面有省略号,所以它就是一个可变模版参数,我们把带省略号的参数称为“参数包”,它里面包含了0到N(N>=0)个模版参数

1.2 STL容器中的empalce系列相关接口

在这里插入图片描述
在这里插入图片描述

首先我们看到的emplace系列的接口,支持模板的可变参数,并且万能引用。那么相对 push_back 和 emplace 系列接口的优势到底在哪里呢?

其实在一般情况下,这两种接口是等价的,但是在插入pair类型时,两者就会有区别

int main()
{bit::list<pair<bit::string, int>> lt1;// 构造pair + 拷贝/移动拷贝 pair 到 list 的节点中的data上pair<bit::string, int> kv("排序", 1);lt1.push_back(kv);// 直接构造pair参数包往下传,直接用pair参数包构造pairlt1.emplace_back("排序", 1);
}

emplace_back总体而言是更高效的

二,lambda表达式

在C++98中,如果自定义类型排序,需要用户定义排序时的比较规则:

struct Goods
{string _name;  // 名字double _price; // 价格int _evaluate; // 评价//.....Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};struct ComparePriceLess
{bool operator()(const Goods& g1, const Goods& g2){return g1._price < g2._price;}
};struct ComparePriceGreater
{bool operator()(const Goods& g1, const Goods& g2){return g1._price > g2._price;}
};int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };// 注意sort的第三个参数要用括号,因为sort是一个函数模板,参数传的是对象// 像优先级队列第三个参数就是要用类型,因为它是一个类模板sort(v.begin(), v.end(), ComparePriceLess());sort(v.begin(), v.end(), ComparePriceGreater());
}

随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法, 都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了Lambda表达式。

2.1 lambda表达式语法

(1) 语法格式

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0c570d33615546a1b99889f76fb4e976.png

(2) 基本使用

int main()
{auto add1 = [](int x, int y)->int {return x + y; };cout << add1(1, 2) << endl;// 函数体中有多条语句时auto func1 = []()->int{cout << "hello bit" << endl;cout << "hello world" << endl;return 0;};func1();cout << endl
}

(3) 一些细节问题

a. 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用

b. 参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略

c. 返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略返回值类型明确情况下,也可省略,由编译器对返回类型进行推导

d. 函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。

代码示例

int main()
{// 无参时,参数列表可以省略,// 知道返回值类型时,返回值类型也可以省略,由编译器自动推导auto func2 = []{cout << "hello bit" << endl;cout << "hello world" << endl;return 0;};cout << func2() << endl;return 0;
}

现在来使用lambda表达式写商品排序问题:

int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,3 }, { "菠萝", 1.5, 4 } };//使用lambad//价格升序sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool{return g1._price < g2._price;});//价格降序sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool{return g1._price < g2._price;});return 0;
}

通过上述例子可以看出,lambda表达式实际上可以理解为匿名函数该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量

2.2 探索lambda底层

函数对象,又称为仿函数,即可以想函数一样使用的对象,就是在类中重载了operator()运算符的类对象。

class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}
private:double _rate;
};int main()
{// 函数对象double rate = 0.015;Rate r1(rate);cout << r1(10000, 2) << endl;// lambda//捕捉列表对象的相当于以成员变量存在lambda类对象中的//捕捉的本质是构造函数的初始化参数auto r2 = [rate](double monty, int year)->double{return monty * rate * year;};cout << r2(10000, 2) << endl;int x = 1, y = 2;auto r3 = [=](double monty, int year)->double{return monty * rate * year;};cout << r3(10000, 2) << endl;return 0;
}

从使用方式上来看,函数对象与lambda表达式完全一样。

函数对象将rate作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可以直接将该变量捕获到

在这里插入图片描述

实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()

三,包装器

3.1 function包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。

使用时要包含头文件:

#include <functional>

类模板原型如下

template <class T> function;     
template <class Ret, class... Args>
class function<Ret(Args...)>;//模板参数说明:
//Ret: 被调用函数的返回类型
//Args…:被调用函数的形参

包装器是用来包装可调用对象:函数指针对象,仿函数对象,lambed

使用方法如下

#include <functional>int f(int a, int b)
{return a + b;
}struct Functor
{
public:int operator() (int a, int b){return a + b;}
};class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};int main()
{// 包装可调用对象:函数指针对象,仿函数对象,lambedfunction<int(int, int)> f1 = f;function<int(int, int)> f2 = Functor();function<int(int, int)> f3 = [](int x, int y){return x + y; };cout << f1(1, 1) << endl;cout << f2(1, 1) << endl;cout << f3(1, 1) << endl;// 包装静态成员函数// 受类域限制,指定类域function<int(int, int)> f4 = Plus::plusi;cout << f4(1, 1) << endl;// 包装非静态成员函数// 方式1:// 1.非静态成员函数取地址要加&符号// 2.还需要传this指针function<double(Plus*,double, double)> f5 = &Plus::plusd;Plus pd;cout << f5(&pd, 1.1, 1.1) << endl;// 方式2:// 可以不传指针,直接传对象function<double(Plus, double, double)> f6 = &Plus::plusd;cout << f6(pd, 1.1, 1.1) << endl; // 有名对象cout << f6(Plus(), 1.1, 1.1) << endl; // 匿名对象return 0;
}

3.2 bind

bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可调用对象,对可调用对象进行参数的调整(参数的顺序,参数的个数)本质返回的是一个仿函数对象

placeholders 是一个命名空间在使用bind进行参数调整时,需要展开

_1代表第一个实参
_2代表第二个实参
_3代表第三个实参
……

在这里插入图片描述

使用方法如下

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;int Sub(int a, int b)
{return (a - b) * 10;
}int SubX(int a, int b, int c)
{return (a - b - c) * 10;
}int main()
{auto sub1 = bind(Sub, _1, _2);cout << sub1(10, 5) << endl;// bind 本身是一个函数模板,本质返回的是一个仿函数对象// 调整参数顺序(不常用)auto sub2 = bind(Sub, _2, _1);cout << sub2(10, 5) << endl;// 调整参数个数(常用)auto sub3 = bind(Sub, 100, _1); // 绑定第1个参数cout << sub3(5) << endl;auto sub4 = bind(Sub, _1, 100); //  绑定第2个参数cout << sub4(5) << endl;// 分别绑死第123个参数auto sub5 = bind(SubX, 100, _1, _2);cout << sub5(5, 1) << endl;auto sub6 = bind(SubX, _1, 100, _2);cout << sub6(5, 1) << endl;auto sub7 = bind(SubX, _1, _2, 100);cout << sub7(5, 1) << endl;//bind 一般用于,绑死一些固定参数function<double(Plus, double, double)> f6 = &Plus::plusd;Plus pd;cout << f6(pd, 1.1, 1.1) << endl; // 有名对象cout << f6(Plus(), 1.1, 1.1) << endl; // 匿名对象function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);cout << f7(1.1, 1.1) << endl; // 有名对象return 0;
}

(1) 调整参数顺序示意图

时刻记住:_1代表第一个实参,_2代表第二个实参

在这里插入图片描述
(2) 调整参数个数的示意图

分别是绑定第1个参数,绑定第2个参数

在这里插入图片描述

四,类的新功能

4.1 默认成员函数

原来C++类中,有6个默认成员函数,C++11 新增了两个:移动构造函数和移动赋值运算符重载

对于新增的两个默认成员函数有一些需要注意的点如下:

  • 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造
  • 默认移动赋值跟上面移动构造完全类似
  • 如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。

代码示例如下

class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}private:bit::string _name;int _age;
};int main()
{Person s1;Person s2 = s1;Person s3 = move(s1);Person s4;s4 = move(s2);return 0;
}

在这里插入图片描述

4.2 关键字default

功能:强制生成默认函数

4.3 关键字delete

功能:禁止生成默认函数

如果能想要限制某些默认函数的生成,在C++98中,是把该函数设置成private,并且只声明不实现,这样只要其他人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。

class Person
{
public:Person(const char* name = "", int age = 0):_name(name), _age(age){}//防拷贝// C++98:只声明不实现,声明为私有
//private:
//	Person(const Person& p);
//	Person& operator=(const Person & p);//C++11//Person(const Person& p) = delete;//Person& operator=(const Person& p) = delete;private:bit::string _name;int _age;
};
http://www.hkea.cn/news/23077/

相关文章:

  • 做网站需要什么资金2022今天刚刚发生地震了
  • 建设网站费用主要包括哪些google商店
  • 专注邯郸建设手机网站贴吧友情链接在哪
  • 网站备案拍照背景志鸿优化网官网
  • 网站百度知道怎么做推广网站搜索引擎优化的方法
  • 网站建设注意哪些问题sem和seo是什么职业岗位
  • 一_建设网站前的市场分析奶茶软文案例300字
  • 做网站智能工具江阴企业网站制作
  • 怎么看网站有没有做推广大数据营销系统多少钱
  • 广东工厂搜索seoseo平台优化服务
  • 网站开发平台 eclipseseo网站推广案例
  • 什么网站做调查能赚钱关键词优化报价推荐
  • 网站开发职业认知小结开发一个app平台大概需要多少钱?
  • 装修公司全包项目seo搜索引擎实训心得体会
  • 爱站网是干什么的长沙关键词排名首页
  • wordpress 教垜四川seo推广公司
  • 东莞市阳光网青岛seo服务
  • 网站弹窗在中间位置企业培训师
  • 整站下载器 安卓版域名解析查询站长工具
  • 跨境自建站模板seo推广是做什么
  • 网站建设与网页设计报告网络营销师报名入口
  • 生成前端页面的网站东莞网络营销全网推广
  • 网站及单位网站建设情况免费男女打扑克的软件
  • 公司有网站有什么好处网上开店如何推广自己的网店
  • 海口网站建设策划关键词排名优化工具有用吗
  • 请问哪里可以做网站汕头seo
  • 访问国外网站速度慢苏州关键词seo排名
  • 做网站备案照片的要求谷歌seo教程
  • wordpress站点全屏新站如何让百度快速收录
  • wordpress 会议 主题推广排名seo