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 ...
golang channel
在 Go 语言(Golang)中,Channel 是一种强大的并发原语,用于在不同的 Goroutine 之间进行安全的通信和同步。它是 Go 语言并发模型(CSP,Communicating Sequential Processes)的核心组成部分之一,旨在通过消息传递实现并发,而不是通过共享内存来实现并发。以下是对 Channel 的详细讲解,包括其概念、用法、特性、以及一些高级用法和注意事项。 一、Channel 的基本概念 什么是 Channel? Channel 是一种类型安全的数据管道,允许 Goroutine 之间通过发送和接收数据进行通信。 Channel 可以看作是一个先进先出(FIFO)的队列,发送到 Channel 的数据会被接收端按顺序读取。 Channel 提供了同步机制,确保发送和接收操作在适当的时机发生,避免了显式的锁机制。 Channel 的核心特性 类型安全:Channel 是强类型的,只能传递特定类型的数据。例如,chan int 只能传递整数。 阻塞行为:发送和接收操作默认是阻塞的,发送者在接收者准备好之前会等待,接收者在有数据可接收...
move_only_function
在C++中,std::move_only_function 是C++23引入的标准库功能,用于表示仅支持移动语义的函数对象(callable object)。它是std::function的变种,但与std::function不同的是,std::move_only_function不要求存储的函数对象是可拷贝的,仅要求可移动,从而支持更广泛的用例,例如存储只支持移动语义的对象(如std::unique_ptr或lambda表达式中的非可拷贝对象)。以下是对std::move_only_function的详细说明,包括其设计、用法、实现规则和注意事项。 1. 什么是 std::move_only_function?std::move_only_function 是一个类模板,定义在 <functional> 头文件中,用于包装可调用对象(如函数指针、lambda表达式、仿函数等),并提供类型擦除(type erasure),使其可以存储不同类型的可调用对象,同时只要求这些对象支持移动构造和移动赋值,而不需要支持拷贝。它是C++23标准的一部分,旨在解决std::func...
cpp特殊函数生成规则
在C++中,特殊成员函数(special member functions)是指由编译器自动生成(或隐式声明)的类成员函数,包括默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数和移动赋值运算符。这些函数在特定情况下会由编译器自动提供,但其生成规则受到类定义和用户提供的声明的影响。以下是C++中特殊成员函数的生成规则的详细说明,基于C++11及以后的标准。 1. 特殊成员函数的种类C++中的特殊成员函数包括以下六种: 默认构造函数 (T::T();) 无参数的构造函数,用于创建对象。 析构函数 (T::~T();) 用于清理对象资源。 拷贝构造函数 (T::T(const T&);) 用于通过复制已有对象来构造新对象。 拷贝赋值运算符 (T& operator=(const T&);) 用于将一个对象的内容复制到另一个已有对象。 移动构造函数 (C++11 引入, T::T(T&&);) 用于通过移动已有对象的资源来构造新对象。 移动赋值运算符 (C++11 引入, T& operator=(...
Java21 新特性
Java 21 是继 Java 17 之后的又一个长期支持(LTS)版本,于 2023 年 9 月 19 日发布,相较于 Java 17 引入了许多新特性和改进,涵盖语言特性、性能优化、并发模型、API 增强等方面。以下是对 Java 21 相比 Java 17 的主要新特性的详细总结,重点突出其提升,并尽量简洁: 1. 语言特性改进 虚拟线程(Virtual Threads,JEP 444,Java 21 正式化) 项目 Loom 的核心成果,引入轻量级线程,极大降低并发编程的开销,适合高吞吐量应用(如 Web 服务)。 与 Java 17 的平台线程相比,虚拟线程无需直接绑定到 OS 线程,创建和管理成本低,可支持百万级并发。 示例: try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10000).forEach(i -> executor.submit(() -> { Thread.sleep(1000...