每个开发者都应该了解的一些C++特性
作为一门编程语言,C++已经进化了很多。 当然,这些改变不是一夜之间发生的。曾几何时,C++缺乏活力,导致人们不太喜欢这门语言。 但是,当 C++标准委员会决定加快转变时,情况就不同了。 自 2011 年以来,C++已经成为一种不断发展的动态语言,而这正是很多人所期许的。 不要误以为是这门语言变得简单了,实际并没有。它仍然是被广泛使用的最难编程语言之一。但是相比于之前的版本,确实对用户更加友好了。 今天,我们深入发掘一下每位开发者都应该了解的新特性(这些新特性从 C++11 时开始出现,距今已有八年历史了)。注意,本文略过了一些高级特性,可能会在以后的内容中详细探讨。 auto 概念 当 C++11 第一次引入 auto,一切都变得更简单了。 auto 的概念是让 c++编译器在编译时自动推断数据的类型,而不是每次都要求你手动声明类型。如果你的数据类型是
这样的,事情会变得非常方便。
看一下第五行。没有 initializer 时你不能声明某些东西,这不难理解。像第五行这样,编译器是无法推断数据类型的。 最初,auto 的使用是非常受限的。在之后的版本中,auto 变得更加强大! 第 7 和第 8 行中,我使用了花括号初始化。这个特性也是 C++11 中新加入的。 记住,当使用 auto 时,必须确保你的编译器可以通过某种方式推断数据类型。 现在问题来了,如果我写 auto a = {1, 2, 3} 会发生什么?会有编译错误吗?这是向量吗? 实际上,C++11 引入了 std::initializer_list 最后,就像前面提到的,当你使用复杂的数据类型时,编译器推断数据类型会非常有用。 不要忘记查看第 25 行!表达式 auto [v1,v2] = itr.second 是 C++17 的新特性。这被称为结构化绑定。在之前的版本中,每个变量必须要分别进行提取,然而结构化绑定会使这个过程方便很多。 另外,如果你想通过引用获取数据,只需要添加一个像 auto &[v1,v2] = itr.second 这样的符号,非常简洁。 lambda 表达式 C++11 引入了 lambda 表达式,该表达式和 JavaScript 中的匿名函数非常相似。它们是没有命名的函数对象,并且基于一些简洁的语法在不同的作用域捕获变量,它们还可以分配给变量。 当你想在代码中快速实现一些小功能但并不想为此单独编写整个函数时,lambda 非常有用。另一种非常普遍的应用是将其作为比较函数。 上面的例子中有很多细节。 首先,要注意到列表初始化为你节省了多少代码。然后是通用的 begin() 和 end(),它们同样也是 C++11 中新添加的。然后是作为数据比较器的 lambda 函数。lambda 函数的参数被声明为 auto,这是 c++14 中新增的。在此之前,是不可以用 auto 作为函数参数的。 这里使用方括号[]作为 lambda 表达式的开始。它定义了 lambda 函数的作用域,即它对局部变量和对象有多少权限。 下面是一些现代 c++中的相关定义:
因此,如果你想在 lambda 函数中将数据转换成其他形式,你可以像下面这段代码一样,利用作用域来使用 lambda。 在上面的例子中,如果你在 lambda 表达式中使用 [factor] 取值的方式获取了局部变量,你就不能在第五行中修改 factor,因为你没有权利这样做。不要滥用你的权限! 最后,注意这里 var 是引用。这保证了在 lambda 函数内的任何改变都会真正改变 vector。 if 或 switch 语句里的初始状态 当我了解了 c++17 的这个特性之后我非常喜欢。 显然,现在你可以在 if/switch 语句块内初始化变量并且进行条件检查了。这对保持代码的紧凑和简洁是非常有帮助的。通常形式如下:
编译时执行 constexpr constexpr 非常酷! 假设你有一些表达式要计算,并且它的值一旦初始化就不会改变。你可以预先计算该值并且作为宏来使用。或者像 C++11 中提供的,你可以使用 constexpr。 (编辑:ASP站长网) |