cpp 11(易学和易用性)
cpp 11新特性(易学和易用性)
1,自动类型推导
1.1,简介
auto 和 decltype 可以自动推导类型在许多场景有着应用
auto: 用于STL的容器遍历,用于泛型编程
decltype: 泛型编程
1.2,注意事项
- auto 必须初始化
- 当变量不是指针或者引用类型时,推导的结果中不会保留 const、volatile 关键字
- decltype 在编译期间完成推导
- 表达式是一个左值,或者被括号 ( ) 包围,使用 decltype 推导出的是表达式类型的引用(如果有 const、volatile 限定符不能忽略)。
1.3,代码
推导注意:
//auto
int tmp = 250;
const auto a1 = tmp;
//a1:const int auto:int
auto a2 = a1;
//a2:int auto:int
const auto &a3 = tmp;
//a3:const int& auto:int
auto &a4 = a3;
//a4:const int& auto:const int
//decltype
int func_int();
decltype(func_int) a = 0;//a的类型为int
decltype(n = n + m) d = 0;//d的类型为 int&
场景应用
//auto
//用于stl的遍历
map<int, string> person;
for (auto it = person.begin(); it != person.end(); ++it)
{
// do something
}
//decltype
//泛型编程
template <class T>
class Container
{
public:
void func(T& c)
{
for (m_it = c.begin(); m_it != c.end(); ++m_it)
{
cout << *m_it << " ";
}
cout << endl;
}
private:
decltype(T().begin()) m_it; // 此处不能确定是T::iterator()还是T::const_iterator
};
int main()
{
const list<int> lst{ 1,2,3,4,5,6,7,8,9 };
Container<const list<int>> obj;
obj.func(lst);
return 0;
}
//返回类型后置
template <typename T, typename U>
// 返回类型后置语法
auto add(T t, U u) -> decltype(t+u)
{
return t + u;
}
int main()
{
int x = 520;
double y = 13.14;
// auto z = add<int, double>(x, y);
auto z = add(x, y); // 简化之后的写法
cout << "z: " << z << endl;
return 0;
}
2,基于范围的for循环
2.1,简介
cpp 11新增for循环方式可更为简洁的遍历容器
2.2,注意事项
- 此种方式遍历范围不可更改,所以不可在遍历中途增删元素
- 使用这种方式遍历关联型容器时是以pair对象取出对象
2.3,代码
#include<iostream>
#include<vector>
#include<map>
#include<string>
using namespace std;
int main(){
vector<int>test{1,2,3,4,5};
map<int,int>mapTest{{1,1},{2,2},{3,3}};
for(auto i:test){
cout<<i<<" ";
}
cout<<endl;
for(auto& i:test){
cout<<i<<" ";
}
cout<<endl;
for(auto i:mapTest){
cout<<i.first<<" "<<i.second<<" ";
}
cout<<endl;
return 0;
}
3,空指针 nullptr
3.1,简介
由于NULL有时在 cpp 中存在歧义,因此便引入了nullptr
3.2,注意事项
- nullptr 可以隐式转换为任何类型的指针
3.3,代码
#include<iostream>
#include<vector>
#include<map>
#include<string>
using namespace std;
int main(){
int* a = nullptr;
double* b = nullptr;
char* c = nullptr;
return 0;
}
4,lambda 表达式
4.1,简介
实现了匿名函数的功能
4.2,注意事项
- 使用值拷贝的方式捕获的变量只能够读(除非用mutable修饰)
- exception: 指定函数抛出的异常,如抛出整数类型的异常,可以使用 throw ();
4.3,代码
class Test
{
public:
void output(int x, int y)
{
auto x1 = [] {return m_number; }; // error
auto x2 = [=] {return m_number + x + y; }; // ok
auto x3 = [&] {return m_number + x + y; }; // ok
auto x4 = [this] {return m_number; }; // ok
auto x5 = [this] {return m_number + x + y; }; // error
auto x6 = [this, x, y] {return m_number + x + y; }; // ok
auto x7 = [this] {return m_number++; }; // ok
}
int m_number = 100;
};
int a = 0;
auto f1 = [=] {return a++; }; // error, 按值捕获外部变量, a是只读的
auto f2 = [=]()mutable {return a++; }; // ok