c++17新特性有:1、对auto表达式推导的规则进行了改变;2、lambda表达式可以捕获“*this”;3、新增inline变量,可以直接将全局变量定义在头文件中;4、条件表达式中支持初始化语句;5、枚举的直接列表初始化等等。
本教程操作环境: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新特性有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!