关键词
constexpr (C++11)
-
定义常量表达式或常量表达式函数
-
修饰变量
constexpr int a = 1 + 2;
-
修饰函数
constexpr int fun(int src) { return src * src; }
优先编译时运算,不能则运行时运算
constexpr (C++17)
if constexpr
编译期判断,符合才会实例化或者进行编译
consteval (C++20)
-
同constexpr
-
编译期判断,符合才会实例化或者进行编译
decltype (C++11)
-
类型推导
decltype(fun()) val; decltype(1) val;
-
完全保留类型;并不执行函数fun()
explicit (C++11)
指定构造函数或转换函数为显式, 即它不能用于隐式转换和复制初始化
class DemoClass
{
public:
explicit DemoClass(int para);
}
DemoClass obj = 10; //error
DemoClass obj(10); //correct
inline (C++11)
内联函数
如果可以将函数运行时调用改为编译时替换,代替宏定义函数(现代编译器大多会主动优化即便未显式内联)
inline int sum(int a, int b)
{
return a + b;
}
inline (C++17)
内联变量
class MyClass
{
inline static std::string m_strValue{"Hello"};
};
// 可以被多个CPP包含
inline MyClass myGlobalObj;
= default (C++11)
让编译器生成默认的构造函数等
= delete (C++11)
显式删除构造函数等
override (C++11)
显式告知编译器进行重载,不是虚函数则报错
final (C++11)
防止类被继续继承或者阻止虚函数被其子类重载
属性
[[ 属性列表 ]] (C++11)
[[deprecated]] (C++14)
废弃的函数、变量等,使用后编译器生成警告
[[deprecated]]
void TriassicPeriod() {
...
}
[[maybe_unused]] (C++17)
屏蔽因未使用的变量、函数等的编译器警告
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
[[maybe_unused]] bool thing2)
{
[maybe_unused]] bool b = thing1 && thing2;
}
声明
using
-
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;
}
}
算法
算法执行策略 (C++17)
std::execution::seq
顺序执行
std::execution::par
并行执行
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;
});
std::execution::par_unseq
并行无序执行
std::execution::unseq
无序执行
类型
作用域枚举
class Demo
{
enum class button {up, down};
enum class ladder {up, bottom};
void open()
{
auto state = button::up;
}
}
函数对象
std::function (C++11)
可包装函数指针、lambda函数、类成员函数等
std::bind (C++11)
绑定函数参数,延迟调用
std::placeholders::_1 (C++11)
绑定函数参数的占位符
std::pair
可具有两个不同数据类型的容器
std::optional (C++17)
可能为空的值
std::optional<int> getSensorValue(bool b)
{
if(b)
return 0;
else
return std::nullopt;
}
if (getSensorValue(false))
{
//空值
}
if (getSensorValue(true))
{
//获得的值为0
}
std::variant (C++17)
类型安全的联合体
std::variant<int, double, std::string> x;
int* i = std::get_if<int>(&x);
if (i == nullptr)
{
//不是int类型
}
else
{
//通过*i取值
}
std::any (C++17)
存储任何类型的单个值的安全容器
std::any a = 1;
a = 2.3;
a = "hello";
int* i = std::any_cast<int>(&a);
if (i == nullptr)
{
//转换失败
}
else
{
//通过*i取值
}
std::move (C++11)
-
移动语义,将左值转换为右值
-
转移智能指针、互斥锁等的所有权
std::forward (C++11)
完美转发,保留参数左右值性传递
std::span (C++20)
连续对象存储的观察者
void print(std::span<int> src)
{
//src.size()=4
for(auto item : src)
{
//遍历数组
}
}
int buf[4]{1,2,3};
print(buf);
类型转换
reinterpret_cast
指针类型转换
int a = 1;
int *p = &a;
char *cp = reinterpret_cast<char*>(p);
static_cast
强制类型转换
int a = 1;
char b = static_cast<char>(a);
字符串转整型等
std::stoi (C++11)
std::from_chars (C++17) (高性能)
整形等转字符串
std::to_string (C++11)
std::to_chars (C++17) (高性能)
内存管理
std::unique_ptr (C++11)
独占资源所有权的指针
std::shared_ptr (C++11)
共享资源所有权的指针
std::weak_ptr (C++11)
共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期
std::enable_shared_from_this<> (C++11)
shared_from_this() (C++11)
在类对象的内部中获得一个指向当前对象的 shared_ptr 对象
字符串
格式化
std::format (C++20) (至高性能)
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!
std::string_view (C++17) (高性能)
只读字符串,读取性能高
文件处理
std::filesystem::exists (C++17)
判断文件或文件夹是否存在
std::filesystem::create_symlink (C++17)
创建文件软链接
std::filesystem::space (C++17)
获得文件系统的空间占用情况
时间处理
std::chrono::system_clock (C++11)
系统提供的实时时钟
std::chrono::steady_clock (C++11)
不会被调整的单调时钟
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::high_resolution_clock (C++11)
当前系统时钟周期最短的时钟
获取时区 (C++20)
std::chrono::current_zone()->get_info(std::chrono::system_clock::now()).offset
std::chrono::milliseconds… (C++11)
时间段
std::chrono_literals (C++14)
时间字面值
编译器宏
__VA_ARGS__
变长参数
__cplusplus
当翻译单元编译为 C++
_WIN32
windows x86或者x64
_WIN64
windows x64
__APPLE__
MacOS
__linux__
Linux
并发
std::thread (C++11)
std::ref (C++11)
按引用传递参数
std::jthread (C++20)
-
支持析构时请求停止线程并等待
-
支持中断请求
std::this_thread::sleep_for (C++11)
延时
std::lock_guard<> (C++11)
作用域锁
std::scoped_lock<> (C++17)
多个无关上锁解锁顺序(避免死锁)的作用域锁
std::unique_lock<> (C++11)
灵活的可移动的作用域锁
std::shared_lock<> (C++14)
可移动的读写锁的作用域锁
Tips: C++17可以自动推断模板类型,因此可以直接定义std::scoped_lock等
std::call_once (C++11)
多个线程仅调用一次
std::latch (C++20)
单次使用的等待多个线程(门闩)
-
计数器为0时,准备就绪,状态直至被销毁
-
同一个线程可以减少多次计数器
-
多个线程可以对计数器减少一次
std::barrier (C++20)
可复用的等待多个线程(屏障)
-
每个线程只能在每个周期到达一次
-
到达后线程阻塞,直到所有线程达到
-
线程再次到达,会等待下一次的所有线程的达到
std::future (C++11)
访问异步操作结果
std::async (C++11)
异步运行一个函数(有可能在新线程中执行)
其他
std::source_location (C++20)
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
信号处理
std::signal(SIGINT, signal_handler);
std::endian (C++20)
获得本机的大小端环境
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";
}
std::numbers::pi (C++20)
数学常数 π
std::size (C++17)
获取数组大小等
char c[4] = { 'a', 'b', 'c' };
//std::size(c)=4
正则表达式 (C++11)
清洗日志中的错误码
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)
{
...
}
结构化绑定 (C++17)
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