【C++11重点语法】lambda表达式,初始化列表
创始人
2024-03-03 10:43:07

目录

引子:C++11为什么的源来

语法1:初始化列表 

        1.2.2 多个对象的列表初始化

语法3:默认成员函数控制(delete,default)

语法4:lambda表达式 


引子:C++11为什么的源来

在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为 C++11之前的最新C++标准名称。打算5年一个标准,打算07年出一个新标准,但是没有完成,把C++07改名叫C++0x,直到11年完成改名问C++11;相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,有很多新东西,其中也有许多鸡肋语法;C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率

语法1:初始化列表 

1.1内置类型的初始化列表

  • 可以使用‘=’
int main(){ // 内置类型变量int x1 = {10};int x2{10};int x3 = 1+2;int x4 = {1+2};int x5{1+2};// 数组int arr1[5] {1,2,3,4,5};int arr2[]{1,2,3,4,5};// 动态数组,在C++98中不支持int* arr3 = new int[5]{1,2,3,4,5};// 标准容器vector v{1,2,3,4,5};map m{{1,1}, {2,2,},{3,3},{4,4}};return 0;}

 1.2自定义类型的列表初始化

1.2.1. 标准库支持单个对象的列表初始化

  • 多参数构造函数,支持隐式类型转换
class Point
{
public:Point(int x = 0, int y = 0): _x(x), _y(y){}
private:int _x;int _y;
};
int main()
{Pointer p{ 1, 2 };return 0;
}

1.2.2 多个对象的列表初始化

C++98支持数组使用列表初始化 ,C++98不支持构造函数列表初始化  

int array1[] = {1,2,3,4,5};
int array2[5] = {0};

C++支持构造函数列表初始化  

vector v{1,2,3,4,5};

原因:1,2,3,4,5,先隐式构造为initializer_list的一个对象,再调用vector对应的构造函数

容器vector的 initializer_list 构造函数和赋值运算符重载

  • initializer_list是系统自定义的类模板,该类接口函数:迭代器 :begin()、end()以及获取区间中元素个数的方法size()
  • 多个对象想要支持列表初始化,需给该类(模板类)添加一个带有initializer_list类型参数的构造函数;
		Vector(initializer_list l): _capacity(l.size()), _size(0){_array = new T[_capacity];for (auto e : l)_array[_size++] = e;}Vector& operator=(initializer_list l) {delete[] _array;size_t i = 0;for (auto e : l)_array[i++] = e;return *this;}

 C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型(vector,list)和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。 

语法2:decltype类型推导

  • 不知道对象或者返回值的类型,decltype是根据表达式的实际类型推演出定义变量时所用的类型
    const int x = 2;const int y = 3;decltype(x+y) z = 3;cout << typeid(z).name() << endl;

 语法3:默认成员函数控制(delete,default)

1.default:显式缺省函数 

  • 默认成员函数都可以使用default

写了拷贝构造函数就不会默认生成构造函数了,就没办法创造一个无参的对象了 

class Person
{
public://person()=default;Person(const char* name,int age):_name(name),_age(age){}
private:string _name;int _age=0;
};
int main()
{Person p;return 0;
}

person()=default ;这句代码就可以让编译器默认生成;

2.delete:删除默认函数,没有办法真正删除,只是不让删除使用

C++98 防拷贝:1、只声明不实现 2、声明成私有 

class A
{
public:A() = default;private:A(const A& a);
};
  1. 只声明不实现 ,调用也不会发生改变
  2.  声明成私有,防止在类外被声明

 C++11:使用A(const A& a)=delete即可

class A
{
public:A() = default;A(const A& a)=delete;
private:};

语法4:lambda表达式 

这里有一组数据,按名称或者按数量,要怎么办了;

pair fruit[] = { {"香蕉",15}, {"菠萝",23},{"柿子",35}, {"芒果",12} };

使用仿函数 

class compareName
{
public:bool operator()(const pair& l, const pair& r){return l.first <= r.first;}
};
class compareNumber
{
public:bool operator()(const pair& l, const pair& r){return l.second <= r.second;}
};
int main()
{pair fruit[] = { {"香蕉",15}, {"菠萝",23},{"柿子",35}, {"芒果",12} };sort(fruit, fruit+ 4, compareNumber());for (int i = 0; i < 4; i++){cout << fruit[i].second << " ";}cout << endl;sort(fruit, fruit + 4, compareName());for (int i = 0; i < 4; i++){cout << fruit[i].first << " ";}
}

每次为了实现一个algorithm算法, 都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便;

使用lambda表达式代码就会简短一些

	pair fruit[] = { {"香蕉",15}, {"菠萝",23},{"柿子",35}, {"芒果",12} };//数量比较sort(fruit, fruit + 4, [](const pair& l, const pair& r)->bool{ return l.second <= r.second; });for (int i = 0; i < 4; i++){cout << fruit[i].second << " ";}cout << endl;//名字比较sort(fruit, fruit + 4, [](const pair& l, const pair& r)->bool { return l.first <= r.first;});for (int i = 0; i < 4; i++){cout << fruit[i].first << " ";}

lambda表达式结构 

lambda表达式语法:

  1. 参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略 
  2. mutable:默认情况下,lambda函数捕捉的是一个const变量,mutable可以取消其常量性使用该修饰符时,参数列表不可省略(即使参数为空),
  3. ->返回值:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略返回值类型明确情况下,也可省略,由编译器对返回类型进行推导
  4. 函数体:在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量

 最简单的一个lambda表达式:[]{};

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

    int a = 10;int b = 20;auto Add = [a, b] {return a + b; };cout<

输出:30; 

5种捕捉:所有捕捉的变量都是被const修饰的;加mutable就取消了常性;

  • [var]:表示  值传递方式捕捉变量;例int a=10;int b=20;[a,b]{return a+b;};
  • var [=]:表示  值传递方式捕获所有父作用域中的变量(包括this)例int a=10;int b=20;[a,b]{return a+b;};
  • [&var]:表示  引用传递捕捉变量var;例int a=10;int b=20;[&a,&b]{int tmp=a;a=b;b=tem;     return a+b;};(引用才可以交换,值传递(拷贝)不可以交换)
  • [&]:表示  引用传递捕捉所有父作用域中的变量(包括this)
  • [this]:表示  值传递方式捕捉当前的this指针

实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,只是简短仿函数的写法;

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...