c++ optional & expected
在 C++ 中,std::optional 和 std::expected 是两个用于处理可能不存在的值或可能失败的操作的现代工具,它们在 C++17 和 C++23 中分别引入,提供了更安全和表达力更强的错误处理机制。以下是对它们的详细说明,包括定义、用途、特性、用法、差异以及实际代码示例。 1. std::optional定义std::optional 是 C++17 引入的标准库组件,定义在 <optional> 头文件中。它表示一个可能存在或不存在的值,类似于“可能有值,也可能为空”的概念。std::optional<T> 可以包含类型为 T 的值,或者为空(std::nullopt)。 用途 用于表示函数可能返回一个值,也可能不返回任何值。 替代传统的“特殊值”(如 nullptr、-1 等)来表示无值的情况,增强代码的可读性和类型安全性。 常用于需要明确区分“无值”和“有值”的场景,如查找操作、初始化状态等。 关键特性 类型安全:std::optional 明确表示值是否有效,避免了隐式的“魔法值”问题。 值语义:std::optional&...
c++ RTTI
下面把 C++ 的 RTTI(Run-Time Type Information,运行时类型信息)系统一次讲清楚,覆盖原理、用法、细节与坑,并给出精简示例。内容“精准”,不绕弯。 什么是 RTTIRTTI 是编译器在多态场景下,为对象保留其动态类型信息,以便在运行时查询和安全转换。标准接口主要有两件事: typeid:拿到对象(或类型)的类型描述 std::type_info。 dynamic_cast:做安全的向下转型(downcast)/交叉转型(cross-cast)。 触发条件:多态类(类里至少有一个 virtual 函数)。非多态类也能用 typeid(T) 或对非多态表达式用 typeid(expr)(这时只给静态类型)。 两个核心工具1. typeid 语义: typeid(T):返回编译期类型 T 的 type_info(无运行期开销)。 typeid(expr): 若 expr 是多态类型的左值/泛左值,结果是动态类型。 否则结果是静态类型,不求值 expr(无副作用)。 返回 const std::type_info&...
c++ const pointer
在 C/C++ 中,const 关键字与指针结合使用时,会产生不同的效果,主要是 const 指针 和 指向 const 的指针 两种情况。这两者在语法、含义和使用场景上有着明显的区别。以下是对这两种指针的详细讲解: 1. 指向 const 的指针定义:指向 const 对象的指针,表示指针指向的内存中的数据是只读的(不能通过该指针修改)。但指针本身的值(即指向的地址)是可以改变的。 语法: const T *ptr; // 或 T const *ptr; T 是数据类型(如 int, char 等)。 const 修饰的是 *ptr,表示指针指向的内容是常量。 这种指针可以指向任何 T 类型的数据(包括非 const 数据),但通过该指针无法修改指向的数据。 特点: 不能通过指针修改指向的数据:*ptr = value 会导致编译错误。 指针本身可以改变:可以让 ptr 指向其他地址。 可以指向非 const 数据:即使指向非 const 数据,也只能以只读方式访问。 示例代码: #include <stdio.h> int main() {...
c++ 中的 xxx_cast
在 C++ 中,提供了四种主要的类型转换操作符(cast),它们统称为 _cast 函数,用于在不同类型之间进行显式类型转换。这些操作符分别是 static_cast、dynamic_cast、const_cast 和 reinterpret_cast。它们取代了 C 风格的强制类型转换(如 (type)expression),提供了更安全、更清晰的类型转换方式。以下是对这四个 _cast 函数的详细讲解,包括它们的用途、语法、特点以及使用场景。 1. static_cast定义static_cast 是一种在编译时进行类型转换的操作符,用于执行相对安全的类型转换。它不会进行运行时类型检查,因此效率较高,但需要程序员确保转换的正确性。 语法static_cast<目标类型>(表达式) 用途 基本数据类型转换:在内置类型之间进行转换,例如 int 到 float、指针类型之间的转换(在安全的情况下)。 类层次结构中的向上转换:将派生类指针或引用转换为基类指针或引用(这是安全的,因为派生类对象总是包含基类部分)。 调用显式构造函数或转换函数:用于调用用户定义的类型转换(例如通...
c++ trap compilation
收集一下奇奇怪怪的玩意。。。。 虚函数的默认参数#include <iostream> using namespace std; class Base { public: virtual void show(int x = 10) = 0; virtual ~Base() { cout << "~Base\n"; } }; class Derive : public Base { public: void show(int x = 20) override { cout << "x = " << x << endl; } ~Derive() override { cout << "~Derive\n"; } }; int main(int argc, char* argv[]) { Base* bb = new Derive(); ...
CRTP
CRTPCRTP = Curiously Recurring Template Pattern。核心形式是:让派生类把自己作为模板参数传给基类 template<typename Derived> struct Base { /* 使用 static_cast<Derived*>(this) 调用派生接口 */ }; struct Derived : Base<Derived> { /* ... */ }; 这是 静态多态(compile-time polymorphism) 的一种实现:基类在编译期就能调用派生类的方法,达成“没有虚函数表、零运行时开销”的多态。 工作原理(Why / How)基类通过 static_cast<Derived*>(this) 或 static_cast<const Derived*>(this) 把自己转回派生类型,然后直接调用派生实现。因为在最终对象内确实包含派生子对象,所以在合法用法下这是安全的(前提:对象确实是 Derived 的实例)...
c++ 中的类型擦除
C++ 中的类型擦除(Type Erasure)详解类型擦除(Type Erasure)是 C++ 中一种高级编程技术,它允许我们在运行时处理不同类型的值,而无需在编译时知道具体的类型信息。这种技术本质上是将类型信息“擦除”或隐藏起来,通过动态多态或其他机制来统一处理多种类型,从而实现更灵活的泛型编程。类型擦除在标准库中被广泛使用,例如 std::function、std::any 和 std::variant 等组件都依赖于它。 下面我将从概念、原理、实现方式、优缺点、实际应用和示例代码等方面详细说明。内容基于 C++11 及后续标准(包括 C++17 和 C++20 的相关改进) 1. 什么是类型擦除?为什么需要它? 定义:类型擦除是一种设计模式,它通过将具体类型的信息隐藏在抽象接口后面,来实现对多种类型的统一处理。简单来说,就是让代码在编译时“忘记”具体的类型,只保留运行时所需的接口或行为,从而允许存储和操作异构类型的值。 为什么需要类型擦除? 泛型编程的局限:C++ 的模板(template)是静态的泛型机制,它在编译时生成具体代码,但无法处理运行时动态类型(如从用户...
c++ ranges
C++20 引入了 Ranges 库(位于 <ranges> 头文件中),这是对标准模板库 (STL) 的重大扩展和泛化。它使得迭代器和算法更强大、更易用,主要通过引入范围 (range) 的概念来实现统一处理各种数据结构(如数组、向量、列表等)。Ranges 库的核心优势在于算法的懒惰求值 (lazy evaluation)、直接操作容器,以及可组合性 (composability),这大大简化了代码编写,避免了传统 STL 中常见的迭代器对 (begin/end) 显式使用。 std::ranges 关键概念 Range:一个范围是一个可迭代的序列,必须提供 begin() 和 end()(哨兵)。示例包括 std::vector、std::array、std::string_view 等,甚至 C 风格数组。 Views:视图是范围的轻量级、懒惰表示,不会复制数据,只在需要时计算。它们是 Ranges 库的核心,用于管道式组合(如使用 | 操作符)。 Adaptors:如 views::filter、views::transform、views::ta...
简明Rust语法介绍
Rust 是一门注重内存安全、性能和并发性的系统编程语言。以下是其核心语法的扩展介绍,涵盖更多细节和实用特性,适合初学者快速了解并深入掌握。 1. 变量与常量 变量:使用 let 声明,默认不可变。使用 mut 允许修改。变量可以被遮蔽(重新声明)。let x = 5; let x = x + 1; // 遮蔽,创建新变量 let mut y = 10; y = 15; 常量:使用 const 声明,需指定类型,全局作用域,值在编译时确定。const MAX_VALUE: u32 = 100_000; // 下划线提高数字可读性 静态变量:使用 static 声明,生命周期贯穿程序运行。static GREETING: &str = "Hello, Rust!"; 2. 数据类型 标量类型: 整数:有符号 (i8, i16, i32, i64, i128),无符号 (u8, u16, u32, u64, u128),以及 isize/usize(与系统架构相关)。 浮点数:f32, f64。 布尔:bool (true, false)。 字符:char (Un...
golang_context
在 Go(Golang)中,context 是一个标准库提供的重要机制,用于控制协程(goroutine)之间的取消、超时、截止时间传递,以及上下文数据传递。它是并发编程中管理协程生命周期和避免资源泄漏的核心工具之一。 一、context 的主要用途 取消协程(Cancellation) 设置超时时间或截止时间(Timeout / Deadline) 跨 API 传递请求范围的数据(如认证信息、trace id) 防止资源泄露(确保任务完成或及时退出) 二、context 的基本接口和实现接口定义(简化)type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key any) any } 四个常用的 context 构造函数 函数 说明 context.Background() 最基础的 context,通常用于 main ...