C++14~C++17
之前我总结过 C++14 的一些东西, 但现在已经 2020 了啊 = =
所以就想着… emm… 虽然项目还是在用 C11 的东西, 连 C14 都没有. 但是! 需求不会留给你学习的时间的!(即使有, 但那对我不成立!) 所以就再看看 C17 的吧(虽然 C20 已经有了, 不过离实现和稳定还有一段时间, 有其他更优先的事情) 顺便对 C14 回顾一下 :happy:
(PS: 这次在下选择了 cppreference 作为参考)
C++14
varaible template
这是一个让我感觉很迷的特性… 简单来说, 就是变量也可以像类和函数那样拥有模板, 例如
1 | // declaration |
查阅过一些信息, 比如在什么地方可以使用他.
一些测试代码:
1 | void f() { |
我感觉可能离它远一点会比较好
测试结果来看. 它的原理类似于一个全局变量…(怎么感觉我在说废话 = =).
generic lambda
cppreference 是这么定义 lambda 的:
Constructs a closure: an unnamed function object capable of capturing variables in scope.
可以捕获作用域中变量的未命名函数对象.
关于 closure 的定义:
In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment.[1] The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.[b] Unlike a plain function, a closure allows the function to access those captured variables through the closure’s copies of their values or references, even when the function is invoked outside their scope.
一种具有第一类函数的实现词法作用域的名称绑定技术. 实现上, 闭合是一个将函数保存与环境一同保存的记录.
环境是一个当闭合被创建时将每个函数的自由变量(局部使用, 在封闭环境中定义)与被绑的名称的值/引用关联的映射.
与普通函数不同的是, 闭合允许函数通过闭合拷贝值/引用方位被捕获的变量. 即使当函数在它们(原来被捕获的变量)作用域外调用.
PS: 概念上来说, 和成员函数极其相似, 其具体实现也和类基本无二.
哦, 差点忘了, C14 说的是 generic lambda, 而非 lambda.
简单来说, 就是一个形似 auto. 实际实现为模板的 lambda.
1 | // generic lambda, operator() is a template with two parameters |
lambda init-capture
就是一个在捕获域里面可以初始化变量(变量自动 auto, 很让人不舒服的是, 我无法自行指定变量类型)的特性.
relaxed restriction of constexpr
C14 扩展了 constexpr. 只要是基本能想到的, 编译器应该在编译期能做到的事情. 在 constexpr 里面都可以做.
比如简单的 if, switch… 参考
binary literals
直译过来就是二进制字面量. 可以参考
这让我很迷惑. 感觉就是 C11 的东西…
digit separators
这个挺好的, 属于代码规范的一种
1 | unsigned long long l1 = 18446744073709550592ull; // C++11 |
return type deducation for function
函数返回类型推导
1 | decltype f() ->auto { |
aggregate class with default non-static member initializers
就是一个对于纯成员变量, 无构造函数的构造优化. 具体参考
C++17
fold expression
用于变长模板的特性, 记住, 然后活用就好了. 规则
class template arugument deduction
类模板参数的推导. 可以更方便了.
1 | vector<int> v{1}; |
non-type template parameters declared with autp
在模板中使用 auto 替代 typename. 既可以推导其类型, 又可以获取其值.
1 | template <typename T, T v> |
两者是等价的. 还有一些其他用途
compile timr if constexpr
一种 if 的编译时版本.
1 | if constexpr (cond1) { |
可以查看 参考
inline variables
内联变量.这个关键字声明的变量具有可以被多次包含的特性. 但同时也有一些规则. 最典型的应该是类静态成员的声明
1 | class A { |
structured binding
一种绑定结构化数据的手段. 参考
initializers of if and switch
If 和 switch 可以有初始化区域了, 就如同 for 一样(while: ?? 那我呢?) 参考
u8 character literal
u8 字面量. 参考 感觉很没用, 程序代码就不该出现 unicode! (注释除外)
simplifield netesd namaspace
简化的嵌套作用域声明. 算是代码可读性的一种.
1 | namespace A{ |
unsing declaration declaring mutiple names
1 | using A::g, A::g; // (C++17) OK: double declaration allowed at namespace scope |
new order of evalution rules
一个有趣的东西 但我始终认为这类迷惑应该是需要避免的.
guaranteed copy elision
一种避免拷贝构造的特性. 参考
这个看起来是编译器做的优化. f() 本来是个无参函数. 但是在调用 f() 是却传了一个外部的地址(v的地址)过去
而其在使用的时候, 也做了相应调整.
lambda capture of *this
可以捕获外部 this 的lambda. (感觉这群人对 lambda 很上心啊… 连续好几个强化了)
constexpr lambda
… 参考
实现了 constexpr 的lambda…
has include
可以通过函数(大概率其实是一种告知编译器的宏) 这也是 C++ 一向的态度了. 换成其他语言, 根本不会将这种编译时相关信息抛给用户. 这是 C++ 的优势, 也是它复杂的根源之一.
atttribute namespace don’t have to repeat
刚说完又来了. 参考
引入具体实现的相关特性.