1、auto类型说明符:
使用auto能让编译器替我们分析出表达式所属的类型;
例如: auto a = 3;//自动推断赋值号右边的表达式返回的类型,并声明a为对应的类型,此时相当于自动声明a为int类型
2、decltype():
返回操作数的数据类型,编译器分析表达式并得到它的数据类型
例如:decltype(3) b = 10;//推断出3的类型为int,并使用推断出来的类型声明b;
3、 范围for语句
for(declaration: expression ) statement
expression可以是初始值列表( {1,2,3,4} )、数组、vector、string等类型的对象.
这些对象的共同特点是拥有能返回迭代器begin和end成员;
例如:
vector<int> V = {1,2,3,4};
for(auto r:V)
{
cout<<v<<endl;//这里的v代表容器中的元素
}
范围for语句的定义来源于与之等价的传统for语句:
for(auto beg = v.begin(),end = v.end();beg!=end;++beg)
{
auto r = *beg;
cout<<r<<endl;
}
所以使用范围for语句需要注意不要在循环中添加/删除元素
4、override ,final
关键字:override
写在形参列表后 用来表示子类重写了父类的虚函数;
例如:virtual void func() override;//提高可读性
关键字:final
写在形参列表后 用来表示虚函数不可以被重写;
写在类名后边,表示类不可以被继承;
5、类型别名:
typedef int myInt;//传统方法
using myInt = int;//新方法,效果同上边一样
6、lambda表达式:
lambda表达式是一个可调用的对象,表示一个可调用的代码单元.可以看作一个未命名的内联函数.
和其他函数类似,lambda具有一个返回值类型、一个参数列表,一个函数体,
但与函数不同,lambda可能定义在函数内部。Lambda形式如下:
[capture list](parameter list)->return type
{ function body }
其中:
[capture list] 捕获列表 lambda所在函数中定义的局部变量的列表
[] // 不捕获任何函数内部变量,即lambda表达式内部不能使用所在函数内部变量
[=] // 以值的形式捕获所在函数内部变量
[&] // 以引用形式捕获所在函数内部变量
[x, &y] // x 以传值形式捕获,y 以引用形式捕获
[=, &z] // z 以引用形式捕获,其余变量以传值形式捕获
[&, x] // x 以值的形式捕获,其余变量以引用形式捕获
( parameter list ) 形参列表 与普通函数相同
{ function type } 函数体 与普通函数相同
可以忽略参数列表和返回值类型,但必须包含捕获列表和函数体
7、标准库bind函数
定义在头文件<functional>中,可以看成一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。
可以用来解决函数的默认参数只能放在最后的问题
调用bind的一般形式:
auto newCallable = bind(callable,arg_list);
newCallable 是一个新的可调用对象,arg_list 是一个逗号分割的参数列表,对应给定的callable的参数。
当我们调用newCallable 时,newCallable 会调用callable,并传递给它arg_list中的参数。
arg_list中包含形如_n的名字,n为整数。这些参数为占位符,表示newCallable中的参数,它们占据了传递给newCallable 的参数的位置。
_1为newCallable的第一个参数,_2为第二个参数,以此类推;
#include <functional>
void callF(int a, int b)
{
printf("a : %d",a);
printf("b : %d",b);
}
int main(int argc, const char * argv[])
{
auto newCallF = std::bind(callF,1,std::placeholders::_2);
newCallF(2,3);//可以通过输出结果验证上述介绍
return 0;
}
8、标准库 function 类型
请先观察下边的代码有什么特点:
int add(int n1,int n2)
{
return n1 + n2;
}
auto sub = [](int n1,int n2)->int
{
return n1 - n2;
};
struct divide
{
int operator()(int n1,int n2)
{
return n1/n2;
}
};
观察发现,上边的代码中"add"、"sub"、"divide"都是执行运算操作,调用形式都相同,但是它们本身的类型却并不相同.
如果我们想把上边这些可调用对象放在一个容器里边是不能实现的。如何解决?
定义在头文件<functional>中,function是一个模板,当创建一个具体的function类型时我们必须提供额外的信息,例如:
function<int (int , int )>
此例声明一个function类型,它可以表示接受两个int类型参数
并且返回值类型为int的可调用对象的类型;
#include <functional>
int main(int argc, const char * argv[])
{
std::function<int(int,int)> f1 = add;
std::function<int(int,int)> f2 = divide();
std::function<int(int,int)> f3 = sub;
map<string,std::function<int(int,int)>> b = {{"+",f1},{"/",f2},{"-",f3}};
return 0;
}