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