前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++17中新特性

C++17中新特性

作者头像
XZAN
发布2019-01-14 23:05:38
4.8K0
发布2019-01-14 23:05:38
举报

1. auto关键字

从c++11开始,auto关键字能够通过初始化器推导出变量的类型。在c++14中,auto关键字的能力进一步提升,能够通过return语句推导出函数的返回类型。

使用auto关键字能够提高编码效率,同时能够简化重构流程。但是,C++11中的auto推导,往往结果与预期的不同。

c++11 中为了支持统一初始化,引入了新的统一初始化语法,如下所示。

代码语言:txt
复制
// c++11
auto x3{ 1, 2 }; // std::initializer_list<int>
auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
auto x5{ 3 };    // std::initializer_list<int>

这三种方式初始化的变量,最终类型推导的结果都是 std::initializer_list<int> , 而不是我们认为的int。 这是因为

当用于auto声明变量的表达式是{}括起来的,推导的型别就会变成 std::initializer_list。

在C++17中,对auto表达式推导的规则进行了改变

代码语言:txt
复制
// c++17
auto x3{ 1, 2 }; // error: not a single element
auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int>
auto x5{ 3 };    // decltype(x5) is int

对比发现, auto x5{3}, 会直接将变量推导成 x5, 而 x3{1, 2} 这种方式也会编译失败。auto推导的规则变得更加直观。

2. lambda表达式

lambda也是c++11中引入的,在C++11中,lambda表达式只能用捕获this,this是当前对象的一个只读的引用。

在C++17中,可以捕获this, this是当前对象的一个拷贝,捕获当前对象的拷贝,能够确保当前对象释放后,

lambda表达式能安全的调用this中的变量和方法。

3. inline变量

Inline 变量, inline变量可以让变量有多于一次的定义。C++17之前,我们定义全局变量,

总需要将变量定义在cpp文件中,然后在通过extern关键字来告诉编译器 这个变量已经在其他地方定义过了。

inline变量出现后,我们可以直接将全局变量定义在头文件中,而不用担心出现redefine的错误信息。

4. 条件表达式中支持初始化语句

c++17中支持在 if 或者switch 语句中进行初始化, 这个能力的出现能够让代码更加的简洁。

代码语言:txt
复制
// c++17之前
map<int, string> c = {{1,"a"}};
{
    auto res = c.insert(make_pair(2, "b"));
    if(!res.second) {
	    cout << "key 1 exist" << endl;
    } else {
	    cout << "insert success, value:" << res.first->second << endl;
    }
}

上面的一段代码,由于res是一个临时变量,不想影响到后面的代码,所以用一对花括号限制了其作用域。但是如果使用c++17的语法,

在if条件中初始化res,则代码就会显得更加简洁

代码语言:txt
复制
// c++17
map<int, string> c = {{1,"a"}};
if(auto res = c.insert(make_pair(2, "b")); !res.second ) {
	cout << "key 1 exist" << endl;
} else {
	cout << "insert success, value:" << res.first->second << endl;
}

c++17的标准库也进行了扩充, 新增了下面几种数据类型:

1. std::variant

std::variant是类型安全的联合体,是一个加强版的 union,variant支持更加复杂的数据类型,例如map,string等等

2. std::optional

std::optional表示一个可能存在的值。 当我们通过函数创建一个对象时,通常使用通过函数返回错误码,而通过出参返回对象本身。

如果通过optional返回创建的实例,就会变得更加直观,

std::optional 提供了下面几个方法:

代码语言:txt
复制
has_value()   // 检查对象是否有值
value()       // 返回对象的值,值不存在时则抛出 std::bad_optional_access 异常
value_or()    // 值存在时返回值,不存在时返回默认值

3. std::any

一个类型安全的可以保存任何值的容器

4. std::string_view

string_view我最早使用的是boost版本的,c++17中的string_view 和 boost类似。

string_view可以理解成原始字符串一个只读引用。 string_view 本身没有申请额外的内存来存储原始字符串的data,

仅仅保存了原始字符串地址和长度等信息。 在很多情况下,我们只是临时处理字符串,本不需要对原始字符串的一份拷贝。

使用string_view可以减少不必要的内存拷贝,可以提高程序性能。相比使用字符串指针,string_view做了更好的封装。

需要注意的是,string_view 由于没有原始字符串的所有权,使用string_view 一定要注意原始字符串的生命周期。

当原始的字符串已经销毁,则不能再调用string_view。

其他特性:

除此之外,C++17还增加了一些其他特性,文中没有一一列出。

  1. bool 表达式不能用 ++, -- 这两个自增(减)运算符了
  2. c++17中异常已经成为了类型系统的一部分,
  3. 枚举的直接列表初始化
  4. 结构化绑定
  5. constexpr if 表达式
  6. map支持merge和extract

C++17的新特性已经编译器的支持情况请参考 compiler_support#cpp17

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. auto关键字
  • 2. lambda表达式
  • 3. inline变量
  • 4. 条件表达式中支持初始化语句
  • 1. std::variant
  • 2. std::optional
  • 3. std::any
  • 4. std::string_view
  • 其他特性:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档