C11
C11标准
{} 初始化(列表初始化)
- 所有容器均支持
{}
的初始化,并且可以不写=
。但要注意保持代码可读性。 - 对于自定义类型,还会调用构造函数。
- 相较于构造函数的单参数隐式类型转换,{}支持多参数的隐式类型转换。
- 并且创建的临时对象同样具有常性。
1 |
|
initializer_list:
对于常量数组,创建了一个新的类型
std::initializer_list
。这样就导致了如下的语句在C++11中不能使用。
const int* ptr1 = {1,2,3};
,因为花括号内会被识别为std::initializer_list
auto::
- 其用于定义变量时,自动识别类型。要求必须进行显示初始化,例如:
auto pf = malloc
创建一个指向malloc
的函数指针。 typeid(var).name()
可以查看var
的类型,返回值是一个字符串。
decltype::
- 也可以自动识别对象,表达式的类型,可以用于定义变量或者作为模板实参。 例如:
decltype<var> new_var
F_Name<decltype(var)> new_var
nullptr::
- 由于C++中NULL被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。
新增容器:
unordered_map
unordered_set
template<class T,std::size_t N> struct array;
静态数组。template<classT,classAllocator = std::allocator<T>> classforward_list;
单链表。
cbein,cend
所有容器均支持emplace。
- emplace系列函数提供了一种在容器中直接构造元素的方法。这与insert或push_back等方法不同,后者通常需要先构造对象然后再将其复制或移动到容器中,而emplace则是在容器的内部直接构造对象,从而避免了不必要的拷贝或移动操作。
1 |
|
包装器
std::function
:一个通用的函数包装器,可以封装任何可调用对象(例如函数指针、Lambda 表达式、函数对象等)。function本质是一个类模板。1
2
3
4
5
6
7
8std::function在头文件<functional>
// 类模板原型如下
template <class T> function; // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;
模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参function的简单使用
1
2
3
4
5
6
7
8
9
10
11
12#include <functional>
#include <iostream>
void print(int x) {
std::cout << x << std::endl;
}
int main() {
std::function<void(int)> func = print;
func(42); // 调用封装的函数
return 0;
}
-
std::bind
:用于绑定函数对象的某些参数,使得可以创建新的函数对象,其中一些参数已经被指定了具体的值。
1 |
|
std::function:用于存储和调用可调用对象的通用包装器。
- 并且包装器可以和
using
一起使用,用于起别名,using也可以用来给模板起别名。
例如:
1 |
|
函数模板——std::bind:
std::bind 的基本用法
std::bind
的语法如下:
1 |
|
function
:要绑定的函数,可以是函数指针、成员函数指针、全局函数或静态成员函数。arg1, arg2, ...
:要绑定到函数的参数。这些参数可以是值、引用或指针。std::placeholders::_1, std::placeholders::_2, ...
:占位符,表示当调用生成的可调用对象时,这些位置将被传递给可调用对象的实际参数所替代。- 如果传递的是一个对象函数,那么还需要加上实例化对象的(
this
)指针。
- 如果传递的是一个对象函数,那么还需要加上实例化对象的(
1 |
|
std::bind
通过绑定特定参数和使用占位符,提供了一种自动适配函数参数的能力。(上述例子中就是)- 绑定的底层是生成了一个仿函数。
1 |
|
原子操作
atomic
会创建一个原子对象。1
2
3static std::atomic<size_t> seq(1);
size_t cur = seq.fetch_add(1);
锁mutex
- **
std::mutex
**:std::mutex
是 C++11 引入的一个同步原语,用于保护共享数据,防止多个线程同时访问,从而避免数据竞争和不一致性。
- **
std::unique_lock
**:
std::unique_lock
是一个灵活的锁管理器,它对std::mutex
(或其他可锁对象,如std::timed_mutex
、std::recursive_mutex
等)进行独占所有权管理。std::unique_lock
的主要特点是:它确保了在其生命周期结束时,互斥量会被自动释放(解锁),从而防止由于忘记手动解锁而导致的死锁或其他问题。std::unique_lock
还提供了比std::lock_guard
更高级的功能,如延迟锁定、提前解锁、尝试锁定和超时锁定等。
- **
std::unique_lock<std::mutex> lock(_mutex);
**:
- 这行代码声明了一个名为
lock
的std::unique_lock
对象,并立即尝试锁定传递给它的std::mutex
对象_mutex
。 - 如果
_mutex
当前被另一个线程锁定,则此线程将阻塞,直到_mutex
可用并被成功锁定。 - 一旦
lock
对象被销毁(通常是在其作用域结束时),它将自动解锁_mutex
。
多种类型转换函数
转换函数 | 用途 | 语法 |
---|---|---|
static_cast |
用于隐式类型转换(提高代码可读性),合理的类型转换,因为它在编译时会进行类型检查。 | static_cast<type>(expression) |
dynamic_cast |
用于在类层次结构中进行安全的向下转换(必须有虚函数)。 | dynamic_cast<type>(expression) |
const_cast |
用于增加或移除变量的 const 或 volatile 属性。 |
const_cast<type>(expression) |
reinterpret_cast |
用于进行低级别的重新解释类型转换。 | reinterpret_cast<type>(expression) |
std::stoi |
将 std::string 转换为 int 类型。 |
std::stoi(string) |
std::stol |
将 std::string 转换为 long 类型。 |
std::stol(string) |
std::stoll |
将 std::string 转换为 long long 类型。 |
std::stoll(string) |
std::stof |
将 std::string 转换为 float 类型。 |
std::stof(string) |
std::stod |
将 std::string 转换为 double 类型。 |
std::stod(string) |
std::stold |
将 std::string 转换为 long double 类型。 |
std::stold(string) |
std::to_string |
将数值类型(int 、float 、double 等)转换为 std::string 。 |
std::to_string(value) |
std::from_chars |
将字符数组或字符串转换为数值类型(C++17 引入)。 | std::from_chars(ptr, ptr_end, value) |
std::to_chars |
将数值类型转换为字符数组(C++17 引入)。 | std::to_chars(ptr, ptr_end, value) |
C11
https://weihehe.top/2024/07/10/C11标准/