欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

c++17新特性有哪些

程序员文章站 2022-03-12 13:25:43
...

c++17新特性有:1、对auto表达式推导的规则进行了改变;2、lambda表达式可以捕获“*this”;3、新增inline变量,可以直接将全局变量定义在头文件中;4、条件表达式中支持初始化语句;5、枚举的直接列表初始化等等。

c++17新特性有哪些

本教程操作环境:windows7系统、C++17版本、Dell G3电脑。

相关推荐:《C++视频教程

C++17中的新特性

1. auto关键字

从c++11开始,auto关键字能够通过初始化器推导出变量的类型。在c++14中,auto关键字的能力进一步提升,能够通过return语句推导出函数的返回类型。 使用auto关键字能够提高编码效率,同时能够简化重构流程。但是,C++11中的auto推导,往往结果与预期的不同。

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

// 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。 这是因为 当用于auto声明变量的表达式是{}括起来的,推导的型别就会变成 std::initializer_list。

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

// 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 语句中进行初始化, 这个能力的出现能够让代码更加的简洁。

// 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,则代码就会显得更加简洁

// 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 提供了下面几个方法:

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还增加了一些其他特性,文中没有一一列出。

  • bool 表达式不能用 ++, – 这两个自增(减)运算符了

  • c++17中异常已经成为了类型系统的一部分,

  • 枚举的直接列表初始化

  • 结构化绑定

  • constexpr if 表达式

  • map支持merge和extract

更多编程相关知识,请访问:编程学习!!

以上就是c++17新特性有哪些的详细内容,更多请关注其它相关文章!

相关标签: c++17