type
status
date
slug
summary
tags
category
icon
password
Modern C++
Modern C++指的是C++11/C++14/C++17/C++20等版本,新增和改进了C++语法,提升开发效率.
nullptr
nullptr是用来替换NULL的
constexpr
常量表达式
constexpr int num = 1 + 2+ 3;
if/switch 变量声明强化
if (int i = num - 1){ }
即判断条件中可以直接声明临时变量.
初始化列表
#include <iostream> #include <string> using namespace std; class Person { public: string name; int age; int sex; const string &getName() const { return name; } int getAge() const { return age; } int getSex() const { return sex; } }; void testInit() { Person person = {"jack", 18, 1}; }
C++11之前的版本初始化比较麻烦,需要写一些无用代码,这之后比较灵活,可以按照上面的方式进行初始化.
结构化绑定
即多返回值的封包/拆包,在Python,Go,Kotlin中比较常见.
#include <iostream> #include <tuple> using namespace std; void testTuple() { auto[x, y, z] = make_tuple(1, false, "hello"); cout << x << y << z << endl; }
auto
即类型推断,不用每个变量声明都声明类型.
需要注意的就是:auto不能用于函数传参,也不能用于推导数组类型
decltype
auto只能用于变量的类型推断,decltype则对表达式类型推断做了补充.
auto x = 1; auto y = 2; decltype(x+y) z;
区间for迭代
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 3, 4}; if (auto itr = std::find(vec.begin(), vec.end(), 3); itr != vec.end()) *itr = 4; for (auto element : vec) std::cout << element << std::endl; // read only for (auto &element : vec) { element += 1; // writeable } for (auto element : vec) std::cout << element << std::endl; // read only }
模板
将一切能在编译期解决的问题放在编译期解决,仅在运行时处理核心的动态服务.
外部模板
template class std::vector<bool>; // 强行实例化 extern template class std::vector<double>; // 不在该当前编译文件中实例化模板
其实就是一个实例化时机的问题.
类型别名模板
模板是用来生成类型的.
类型别名一般这样用:
typedef 原名称 新名称
对于复杂一点的就显得很难看,可以使用
using
:typedef int (*process)(void *); using NewProcess = int(*)(void *); template<typename T> using TrueDarkMagic = MagicType<std::vector<T>, std::string>; int main() { TrueDarkMagic<bool> you; }
委托构造
#include <iostream> class Base { public: int value1; int value2; Base() { value1 = 1; } Base(int value) : Base() { // 委托 Base() 构造函数 value2 = value; } }; int main() { Base b(2); std::cout << b.value1 << std::endl; std::cout << b.value2 << std::endl; }
没什么好说的,其他语言在设计的时候就已经支持了.
继承构造
#include <iostream> class Base { public: int value1; int value2; Base() { value1 = 1; } Base(int value) : Base() { // 委托 Base() 构造函数 value2 = value; } }; class Subclass : public Base { public: using Base::Base; // 继承构造 }; int main() { Subclass s(3); std::cout << s.value1 << std::endl; std::cout << s.value2 << std::endl; }
overide , final
struct Base { virtual void foo(int); }; struct SubClass: Base { virtual void foo(int) override; // 合法 virtual void foo(float) override; // 非法, 父类没有此虚函数 };
struct Base { virtual void foo() final; }; struct SubClass1 final: Base { }; // 合法 struct SubClass2 : SubClass1 { }; // 非法, SubClass1 已 final struct SubClass3: Base { void foo(); // 非法, foo 已 final };
这两点也没什么好说的,其他语言早就支持了.
Lambda
[捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 { // 函数体 }
值捕获
void lambda_value_capture() { int value = 1; auto copy_value = [value] { return value; }; value = 100; auto stored_value = copy_value(); std::cout << "stored_value = " << stored_value << std::endl; // 这时, stored_value == 1, 而 value == 100. // 因为 copy_value 在创建时就保存了一份 value 的拷贝 }
引用捕获
void lambda_reference_capture() { int value = 1; auto copy_value = [&value] { return value; }; value = 100; auto stored_value = copy_value(); std::cout << "stored_value = " << stored_value << std::endl; // 这时, stored_value == 100, value == 100. // 因为 copy_value 保存的是引用 }
范型Lambda
auto add = [](auto x, auto y) { return x+y; }; add(1, 2); add(1.1, 2.2);
函数对象包装器
如果不使用
std::fucntion()
是这样子的:#include <iostream> using foo = void(int); // 定义函数类型, using 的使用见上一节中的别名语法 void functional(foo f) { // 定义在参数列表中的函数类型 foo 被视为退化后的函数指针类型 foo* f(1); // 通过函数指针调用函数 } int main() { auto f = [](int value) { std::cout << value << std::endl; }; functional(f); // 传递闭包对象,隐式转换为 foo* 类型的函数指针值 f(1); // lambda 表达式调用 return 0; }
使用了之后是这样的:
#include <functional> #include <iostream> int foo(int para) { return para; } int main() { // std::function 包装了一个返回值为 int, 参数为 int 的函数 std::function<int(int)> func = foo; int important = 10; std::function<int(int)> func2 = [&](int value) -> int { return 1+value+important; }; std::cout << func(10) << std::endl; std::cout << func2(10) << std::endl; }
- 作者:姜康
- 链接:https://jiangkang.tech/article/7dbd0838-8cd8-417e-8350-1fbd43234503
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。