定义常量表达式或常量表达式函数
修饰变量
constexpr int a = 1 + 2;
修饰函数
constexpr int fun(int src)
{
return src * src;
}
优先编译时运算,不能则运行时运算
if constexpr
编译期判断,符合才会实例化或者进行编译
同constexpr
编译期判断,符合才会实例化或者进行编译
类型推导
decltype(fun()) val;
decltype(1) val;
完全保留类型;并不执行函数fun()
指定构造函数或转换函数为显式, 即它不能用于隐式转换和复制初始化
class DemoClass
{
public:
explicit DemoClass(int para);
}
DemoClass obj = 10; //error
DemoClass obj(10); //correct
内联函数
如果可以将函数运行时调用改为编译时替换,代替宏定义函数(现代编译器大多会主动优化即便未显式内联)
inline int sum(int a, int b)
{
return a + b;
}
内联变量
class MyClass
{
inline static std::string m_strValue{"Hello"};
};
// 可以被多个CPP包含
inline MyClass myGlobalObj;
让编译器生成默认的构造函数等
显式删除构造函数等
显式告知编译器进行重载,不是虚函数则报错
防止类被继续继承或者阻止虚函数被其子类重载
废弃的函数、变量等,使用后编译器生成警告
[[deprecated]]
void TriassicPeriod() {
...
}
屏蔽因未使用的变量、函数等的编译器警告
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2)
{
[maybe_unused]] bool b = thing1 && thing2;
}
using namespace 命名空间名
导入命名空间
using 命名空间名 :: 成员名
导入命名空间中的某成员
代替typedef指定别名 (C++11)
using func_t = void (*) (int, int);
class Base
{
private:
int val = 0;
}
class Demo: public Base
{
public:
using Base::val;
Demo(int para)
{
val = para;
}
}
顺序执行
并行执行
int x = 0;
std::mutex m;
int a[] = {1,2};
std::for_each(std::execution::par, std::begin(a), std::end(a),
[&](int)
{
std::lock_guard<std::mutex> guard(m);
++x;
});
并行无序执行
无序执行
class Demo
{
enum class button {up, down};
enum class ladder {up, bottom};
void open()
{
auto state = button::up;
}
}
可包装函数指针、lambda函数、类成员函数等
绑定函数参数,延迟调用
绑定函数参数的占位符
可具有两个不同数据类型的容器
可能为空的值
std::optional<int> getSensorValue(bool b)
{
if(b)
return 0;
else
return std::nullopt;
}
if (getSensorValue(false))
{
//空值
}
if (getSensorValue(true))
{
//获得的值为0
}
类型安全的联合体
std::variant<int, double, std::string> x;
int* i = std::get_if<int>(&x);
if (i == nullptr)
{
//不是int类型
}
else
{
//通过*i取值
}
存储任何类型的单个值的安全容器
std::any a = 1;
a = 2.3;
a = "hello";
int* i = std::any_cast<int>(&a);
if (i == nullptr)
{
//转换失败
}
else
{
//通过*i取值
}
移动语义,将左值转换为右值
转移智能指针、互斥锁等的所有权
完美转发,保留参数左右值性传递
连续对象存储的观察者
void print(std::span<int> src)
{
//src.size()=4
for(auto item : src)
{
//遍历数组
}
}
int buf[4]{1,2,3};
print(buf);
指针类型转换
int a = 1;
int *p = &a;
char *cp = reinterpret_cast<char*>(p);
强制类型转换
int a = 1;
char b = static_cast<char>(a);
独占资源所有权的指针
共享资源所有权的指针
共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期
在类对象的内部中获得一个指向当前对象的 shared_ptr 对象
int i = 1000;
float j = 3.1415926;
std::cout << std::format("{:#x}", i) << std::endl;
// 0x3e8
std::cout << std::format("{:.2f}", j) << std::endl;
// 3.14
std::cout << std::format("{1} {0}!", "Hello", 4, "something") << std::endl;
//4 Hello!
只读字符串,读取性能高
判断文件或文件夹是否存在
创建文件软链接
获得文件系统的空间占用情况
系统提供的实时时钟
不会被调整的单调时钟
auto start = std::chrono::steady_clock::now();
testFunc();
auto end = std::chrono::steady_clock::now();
auto elapsed_seconds = std::chrono::duration<double> (end-start);
std::cout << "elapsed time: " << elapsed_seconds.count() << "s" << std::endl;
当前系统时钟周期最短的时钟
std::chrono::current_zone()->get_info(std::chrono::system_clock::now()).offset
时间段
时间字面值
__VA_ARGS__
变长参数
__cplusplus
当翻译单元编译为 C++
_WIN32
windows x86或者x64
_WIN64
windows x64
__APPLE__
MacOS
__linux__
Linux
按引用传递参数
支持析构时请求停止线程并等待
支持中断请求
延时
作用域锁
多个无关上锁解锁顺序(避免死锁)的作用域锁
灵活的可移动的作用域锁
可移动的读写锁的作用域锁
Tips: C++17可以自动推断模板类型,因此可以直接定义std::scoped_lock等
多个线程仅调用一次
单次使用的等待多个线程(门闩)
计数器为0时,准备就绪,状态直至被销毁
同一个线程可以减少多次计数器
多个线程可以对计数器减少一次
可复用的等待多个线程(屏障)
每个线程只能在每个周期到达一次
到达后线程阻塞,直到所有线程达到
线程再次到达,会等待下一次的所有线程的达到
访问异步操作结果
异步运行一个函数(有可能在新线程中执行)
void log(std::string_view message, const std::source_location& location = std::source_location::current())
{
std::cout << "info:" << location.file_name() << ':' << location.line() << ' '
<< message << '\n';
}
int main()
{
log("Hello world!");
}
info:main.cpp:15 Hello world!
信号处理
std::signal(SIGINT, signal_handler);
获得本机的大小端环境
if constexpr (std::endian::native == std::endian::big)
{
std::cout << "big-endian\n";
}
else if constexpr (std::endian::native == std::endian::little)
{
std::cout << "little-endian\n";
}
else
{
std::cout << "mixed-endian\n";
}
数学常数 π
获取数组大小等
char c[4] = { 'a', 'b', 'c' };
//std::size(c)=4
清洗日志中的错误码
std::regex reg("Mem Error:(\\w+),");
std::string str = "Mem Usage Status, Mem Error:e2, Mem Define, Mem Error:e7, Mem Close, Example End, Mem Error:e6.";
const std::sregex_iterator end;
for (std::sregex_iterator iter{ std::cbegin(str), std::cend(str), reg }; iter != end; ++iter)
{
std::cout << "Mem Error: " << \ (*iter)[1].str() << std::endl;
}
//Mem Error: e2
//Mem Error: e7
int a[]{0, 1, 2, 3, 4, 5};
for (int n : a)
{
...
}
int a[2] = {1, 2};
auto [x, y] = a;
// x=a[0],y=a[1]
auto& [xr, yr] = a;
// xr 指代 a[0],yr 指代 a[1]
struct MyStruct {
int i = 0;
std::string s;
};
MyStruct ms;
auto [u, v] = ms;
//u=ms.i, v=ms.s