constexpr 常量表达式关键字,编译器会在编译时期计算表达式,而不是运行时计算。
auto 编译器自动推导变量的类型。
decltype(表达式或变量) 计算表达式或变量的最终类型,而不计算表达式。
尾返回类型 template<typename T, typename U> auto add(T x, U y) -> decltype(x+y) { return x+y; }
外部模板 template class std::vector<bool>; // 强行实例化 extern template class std::vector<double>; // 不在该编译文件中实例化模板
模板套用 std::vector<std::vector<int>> wow;
using 与 typedef 两者作用相同,前者更易阅读。
范围for循环 int array[] = {1,2,3,4,5}; for(auto &x : array) { std::cout << x << std::endl; }
委托构造:一个类的构造函数可以在初始化列表中调用本类的其他构造函数。
继承构造 一个类可以通过using关键字直接声明父类的构造函数
overload 和 final 前者指定该函数为重载父类的同名函数,后者指定子类不可以重载该函数。
枚举类,只有同一个类型的枚举才可以相互比较。
opreator ()()函数执行操作符。
函子类,拥有函数执行操作符的类就可以称作函子类。相当于函数对象。
std::function<返回类型(参数)> 函数包装器。把函数包装成对象。
lembda表达式[捕获的外部变量](参数){函数体}。lembda表达式可以当作函数指针被传递。也可以创建一个临时的函子对象。lemba表达式的参数类型可以是auto的,这种写法类似于模板函数。函数包装器同样可以包装lembda表达式。
右值引用 左值是赋值表达式执行后依然可以存在的值,右值是赋值表达式时会产生一个临时副本,赋值后删除。右值引用就是临时副本的引用,这会让临时副本继续保留不被销毁。
移动语义 移动语义和rust的所有异曲同工之妙,rust的所有权转移由编译器时间,所有权检测在编译期间进行。c++的转移语义需要自己重=运算符,通过传递右值引用保证临时副本不销毁,在进行浅拷贝然后把旧对象的成员指针置成nullptr。c++不能够检测到所有权的转移。
引用参数传递塌缩规则
只有实参和形参都为右引用时传递的参数才会被认定为右引用。
move和forward<T> std::move可以把传递的左值转换成右值。std::forword<T>函数可以判断出传递的参数最原始时是做之还是右值。
std::tuple 元组。
智能指针(强引用计数)std::shared_ptr 记录内部指针的引用计数,并在引用计数为0时删除内部指针
智能指针(弱引用计数)std::weak_ptr 弱引用计数对象创建不会引起引用计数的增加。
智能指针(独占指针)不允许被复制,但是可用通过move移动到其他指针。类似所有权转移。
std::lock_gurad 该对象会持有传入的std::mutex并进行lock在栈推出时执行unlock
std::unique_lock 该对象独占传入的std::mutex,只能够通过move转移所有权。其他行为与上述相同
std::package 和 std::future 前者用于封装异步调用对象,后者通过该对象获取异步调用的结果
std::condition_variable 为了防止死锁而使用该对象唤醒一个线程。
noexcept关键字 该函数不能抛出异常。