从零开始的C++(二十一)

C++11

1.列表初始化:

复制代码
//允许以下代码正确运行

int a[]{1,2,3};//效果与int a[]={1,2,3}一致

即允许省略等于号。同时,允许用花括号对所有自定义类型和内置类型进行初始化,而非以前花括号只能对数组进行初始化。利用花括号对自定义类型初始化时,相当于调用了其构造函数。

2.std::initializer_list

一般用作构造函数的参数,接受一系列的初始值,并以此赋给每个对象。

因此,允许以下操作:

复制代码
map<int,string>v={{1,"one"},{2,"two"}};
//其中{1,"one"}和{2,"two"}均对应一个pair<int,string>的对象,用于给map赋值。

3.decltype

可以获得变量的类型,并且可以用这个类型构造变量(与typeid不同,typeid只能得到类型,不能用来定义变量)

4.右值引用

左值:可以取地址的表达式,因为可以取地址因此可以给其赋值,所以可以出现"="的左右任意一侧。对左值进行引用,就是给其取个别名,称为左值引用。

右值:不可以取地址的表达式,无法给其赋值,因此只能出现在"="右侧,对右值进行引用,称为右值引用。常见的右值有表达式返回值、常量、函数返回值(返回非左值引用的类型才行)。

需注意,右值不能取地址,无法给其赋值,但是,右值引用后会有一份地址保存这个值,就可以通过这个地址对其进行修改。若不希望被修改,就用const修饰右值引用。

左值引用与右值引用区别:

左值引用:正常只能引用左值,用const修饰可以引用左值和右值

右值引用:正常只能引用右值,但是给左值加move可以被右值引用

复制代码
int i=1;
int &&a=move(i);  //此处i是左值,但move(i)返回的是右值

右值引用应用:

常用于函数返回临时对象时,此时无法返回左值引用,因为变量是出了函数作用域就销毁的。若不用右值引用,则正常需要进行两次深拷贝(编译器可能优化成一次),但右值引用可以不进行深拷贝,极大提高了效率。

而右值引用的原理是,认为临时对象出了作用域就要被销毁,因此可以直接拿过来临时对象的成员,这样就不用进行深拷贝了。这就是移动构造的思想。

同时,也有移动赋值,函数参数是右值引用,原理也是直接交换对象的成员,而非深拷贝。

5.完美转发:

用于有万能模版的情况下。而万能模版就是一种特殊的模版函数,其成员是T&&val,此时可以接受左值引用也可以接受右值引用,因此是万能模版。而无论是左值引用还是右值引用,其类型都是左值(注:是右值引用是左值,不是右值是左值!),因此,若用右值引用做参数,只能调用以左值引用为形参的函数,无法调用以右值为形参的函数,若想要调用只能用move,但这样就只能调用右值引用为参数的。为了实现左值引用可以调用左值为参数的函数,右值引用可以调用右值为参数的函数,在引用前加一个forward,效果是右值引用则返回一个右值,左值引用就返回一个左值。

6.默认成员函数的增加:

增加了默认移动构造和默认移动赋值构造,编译器自己写默认移动构造函数的前提是:

1.用户自己未编写移动构造

2.用户为编写拷贝构造、赋值构造和析构函数。

使用:对于内置类型进行逐字节拷贝,对于自定义类型若有移动构造调用移动构造,若没有调用拷贝构造。

(对于默认移动赋值前提和使用极其类型,就是把移动构造改成移动赋值即可)

7.强制生成/销毁默认成员函数:

强制生成:default; 强制销毁:delete 一般称=delete的函数是删除函数

复制代码
class bb
{
   public:
   
   bb()=default;//强制生成
   
   bb(const bb&b)=delete;//强制删除

}

8.可变参数模版:

写法:

template<class...Args>

返回类型 函数名(Args...args)

{

//函数体

}

args前面有...,是可变模版参数。称前面有...的参数为参数包,参数包里包含0到N个可变模版参数。

如何获取参数包里的可变模版参数:

1.用递归展开:

复制代码
void _get()
{
	cout<< endl;
}

template<class T,class...Args>
void _get(T& val,Args...args)
{
	cout << val << " ";
	_get(args...);
}

template<class...Args>
void get(Args...args)
{
	_get(args...);
}

int main()
{
	get(1, 2.2, "xxx");
}

原理就是不断用T获取最左的那个可变模版参数,然后不断缩小参数包内的可变模版参数的个数,最后当可变模版参数为0时调用打印空格,实现获取所有的参数。

2.利用逗号表达式:

复制代码
template<class T>
void print(T& val)
{
	cout<< val << " ";
}

template<class...Args>
void get(Args...args)
{
	//_get(args...);

	int a[] = { (print(args),0)... };
	cout << endl;
}

原理是利用初始化列表展开成(print(args1),0)、(print(args2),0)...,同时利用逗号表达式依次去执行每个()内的两条表达式,实现获取每个参数。

9.lambda表达式

形式:

\]+()+mutable+-\>+{}; 其中: \[\]:捕捉列表,包含在于lamabda相同作用域内的变量.\[var\]表示捕获变量var。\[=\]表示捕获父作用域内所有变量。\[\&var\]表示捕获var变量的引用。\[\&=\]表示父作用域所有变量的引用。\[this\]表示捕获当前的this指针。\[\]内可以包含多钟类型的捕捉,比如\[\&var1,var2,this\],但注意相同变量不能重复捕获。 ():函数参数列表,若无参数可以省略 mutable:若无mutable则表示该lambda函数是const修饰的函数,若有则可以取消常量性。注:若加上mutable,则参数列表无论有无参数都得写"()"。 -\>:指向返回类型,若返回类型是空可以省略,若返回类型十分明确也可以省略让编译器自动推导。 {}:函数体部分。 ps:只有\[\]和{}部分一定不能省略 lambda的底层代码是仿函数,若想要用一个变量接受该表达式,则需要用auto修饰变量,因为lambda返回的类型由编译器自己决定,无法显示知道并调用。 10.包装器: 头文件是\ function\<返回类型(函数参数)\>对象={}。 作用:可以让对象赋值为仿函数、函数形参、lambda函数(但返回类型和函数参数必须相同) (注:当接受的是lambda函数时,不管\[\],只要()和返回类型一致就行) 11.bind: 类型一个函数模版。功能是接受一个可调用对象,返回一个新的可调用对象去适应原本的函数参数,如修改函数参数的先后顺序和个数。 使用: auto newcallable=bind(callable,arg_list),其中newcallable是新生成的可调用对象,callable是原可调用对象,arg_list是一个逗号表达式,包含callable的参数。 arg_list:可以是placeholder::_x,表示当前位置对应函数第x个参数。 ![](https://file.jishuzhan.net/article/1733775540722077697/fb9a489292d940437a6a30e11daf2214.webp) 如上图,newf中1对应的是placeholder::_2,故对应lambda的第二个函数参数b。 arg_list也可以是一个固定变量或常量,表示该位置是一个固定的函数参数,一般用于某个调用的参数固定不变的情况。 ![](https://file.jishuzhan.net/article/1733775540722077697/e277ee45a04e98693dc2581cf17eaa35.webp) 如上图,第一个参数a对应的位置为常量111,此时调用时就不需要在显示写该参数了,因此newf调用时只写了一个参数。

相关推荐
白总Server15 分钟前
GaussDB 分布式数据库调优(架构到全链路优化)
java·网络·c++·架构·go·scala·数据库架构
whoarethenext1 小时前
C++/OpenCV地砖识别系统结合 Libevent 实现网络化 AI 接入
c++·人工智能·opencv
CPETW1 小时前
同旺科技 USB TO SPI / I2C适配器(专业版)--EEPROM读写——C
c语言·开发语言·科技·stm32·单片机·嵌入式硬件·电子
Antonio9151 小时前
【Linux】Linux基础I/O
linux·c++
代码中の快捷键1 小时前
如何实现一个登录功能?
java·开发语言
虾球xz1 小时前
CppCon 2015 学习:C++ devirtualization in clang
开发语言·c++·学习
呆呆的小鳄鱼1 小时前
IO之详解cin(c++IO关键理解)
linux·c语言·c++
看到我,请让我去学习2 小时前
C++核心编程(动态类型转换,STL,Lanmda)
c语言·开发语言·c++·stl
conkl2 小时前
Apache网页优化实战指南 - 让网站加载速度提升
linux·运维·服务器·开发语言·阿里云·apache
羚羊角uou2 小时前
【C++】模拟实现map和set
java·前端·c++