C++11新特性


title: C++11新特性
author: 陈德强
date: 2019-09-30 22:12:00
categories:

  • C++
    tags:
  • C++
    toc: true
    top: false
    img: /medias/paperimg/c.jpg
    summary: C++11新特性。
    ---

一、nullptr

nullptr比NULL更安全。当需要使用NULL时,应使用nullptr代替。

二、auto

自动推断变量类型,常用于迭代器。

三、decltype

自动推断表达式类型。decltype(表达式)

int x = 1;
int y = 2;
decltype(x+y) z;

四、拖尾返回类型

用于模板类的后置返回类型。

template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y) 
{
    return x+y;
}

从 C++14 开始是可以直接让普通函数具备返回值推导,因此下面的写法变得合法:

template<typename T, typename U>
auto add(T x, U y)
 {
    return x+y;
}

五、for增强

基于范围的for循环,多用于遍历容器。for(int a:vector){}
迭代器时是指针,非迭代器时是基本类型。
因此,迭代器++是地址(指针)++,基本类型++是数值++。
在顺序取值时使用基本类型,需要特殊位置取值时使用迭代器。

#include <iostream>
#include <vector>

int main() {
   std::vector<int> arr(5, 100);
   std::cout << "Start:" << std::endl;
   std::cout << "--------非引用(只读)-----------" << std::endl;
   for (auto i : arr) {
      std::cout << i << std::endl;
   }
   std::cout << "--------引用(读写)-----------" << std::endl;
   for (auto &i : arr) {
      std::cout << i << std::endl;
      i++;
   }
   std::cout << "---------测试引用输出----------" << std::endl;
   for (auto i : arr) {
      std::cout << i << std::endl;
   }
   std::cout << "--------迭代器-----------" << std::endl;
   for (auto i = arr.begin(); i != arr.end(); i++)
   {
      std::cout << *i << std::endl;
   }
   system("pause");
   return 0;
}
Start:
--------非引用(只读)-----------
100
100
100
100
100
--------引用(读写)-----------
100
100
100
100
100
---------测试引用输出----------
101
101
101
101
101
--------迭代器-----------
101
101
101
101
101
Press any key to continue . . .

六、列表初始化

C++11允许所有类型使用列表初始化方式,{}
同时也支持自定义类型的列表初始化方式:(待补充)

#include <initializer_list>

class Magic {
public:
    Magic(std::initializer_list<int> list) {}
};

Magic magic = {1,2,3,4,5};
std::vector<int> v = {1, 2, 3, 4};

七、模板增强

7.1 外部模板

template class std::vector<bool>;            // 强行实例化
extern template class std::vector<double>;  // 不在该编译文件中实例化模板

7.2 尖括号 “>”

在传统 C++ 的编译器中,>>一律被当做右移运算符来进行处理。但实际上我们很容易就写出了嵌套模板的代码:

std::vector<std::vector<int>> wow;

这在传统C++编译器下是不能够被编译的,而 C++11 开始,连续的右尖括号将变得合法,并且能够顺利通过编译。

7.3 类型别名模板

在传统 C++中,typedef 可以为类型定义一个新的名称,但是却没有办法为模板定义一个新的名称。因为,模板不是类型。
C++11 使用 using 引入了下面这种形式的写法,并且同时支持对传统 typedef 相同的功能:

template <typename T>
using NewType = SuckType<int, T, 1>;    // 合法

八、构造函数

8.1 委托构造

C++11 引入了委托构造的概念,这使得构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的:

class Base {
public:
    int value1;
    int value2;
    Base() {
        value1 = 1;
    }
    Base(int value) : Base() {  // 委托 Base() 构造函数
        value2 = 2;
    }
};

8.2 继承构造

使用using可以直接完成基类的“透传”构造函数。
多重继承有一定的限制,暂不考虑。
如果一个继承构造函数不被相关的代码使用,编译器不会为之产生真正的函数代码,这样比透传基类各种构造函数更加节省目标代码空间。

struct A
{
  A(int i) {}
  A(double d,int i){}
  A(float f,int i,const char* c){}
};
struct B:A
{
  using A::A;
  //关于基类各构造函数的继承一句话搞定
  //to do something......
};

九、Lambda表达式

Lambda 表达式,实际上就是提供了一个类似匿名函数的特性,而匿名函数则是在需要一个函数,但是又不想费力去命名一个函数的情况下去使用的。
同时,当某个函数只能传递一个参数,实际中却需要传入两个参数来解决时可以运用Lambda表达式。
Lambda 表达式的基本语法如下:

[ caputrue ] ( params ) opt -> ret { body; };

1) []不捕获任何变量。
2) [&]捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
3) [=]捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。注意值捕获的前提是变量可以拷贝,且被捕获的变量在 lambda 表达式被创建时拷贝,而非调用时才拷贝。如果希望lambda表达式在调用时能即时访问外部变量,我们应当使用引用方式捕获。
4) [=,&foo]按值捕获外部作用域中所有变量,并按引用捕获foo变量。
5) [bar]按值捕获bar变量,同时不捕获其他变量。
6) [this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。

通常情况下,[]都是空:

stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size();});

十、新增容器

10.1 std::array

array是数组的替代品,除了可以随机访问元素,还具有一些迭代器功能。

std::array<int, 4> arr= {1,2,3,4};

以下行为不可:

int len = 4;
std::array<int, len> arr = {1,2,3,4}; // 非法, 数组大小参数必须是常量表达式

10.2 std::list

std::list是单向列表,当不需要双向迭代时,具有比 std::list 更高的空间利用率。

10.3 无序容器

C++11 引入了两组无序容器:
std::unordered_map/std::unordered_multimap 和 std::unordered_set/std::unordered_multiset。
TODO:)
参考:
https://purethought.cn/2019/09/25/%E7%BC%96%E7%A8%8B/C/%E5%85%B3%E8%81%94%E5%AE%B9%E5%99%A8%E6%80%BB%E7%BB%93/

10.4 std::tuple元组

TODO:)

十一、正则表达式

TODO:)

十二、语言级线程支持

std::thread
std::mutex/std::unique_lock
std::future/std::packaged_task
std::condition_variable

十三、右值引用和移动语义

TODO:)

参考链接:
https://blog.csdn.net/jiange_zh/article/details/79356417
https://blog.csdn.net/y396397735/article/details/79615834

转载于:https://www.cnblogs.com/chendeqiang/p/11612953.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值