详谈C++各版本升级点

部分内容找AI完善了,AI就是好用啊

1. C++11(2011年发布)

版本说明:

C++11(正式标准编号 ISO/IEC 14882:2011)是 C++ 语言历史上首个重大现代修订版本,于 2011 年 8 月 12 日由国际标准化组织(ISO)正式发布。其开发代号曾为 "C++0x",最终因标准制定延期而定名 "C++11"。该版本在 C++98/03 基础上进行了深度重构,标志着 C++ 进入现代化阶段。核心亮点在于保留语言底层控制能力的同时,引入现代编程范式,显著提升开发效率、类型安全和性能。C++11 的兼容性设计保证了旧代码的平滑迁移(仅需编译器支持新语法),成为后续 C++ 标准的基石,也是当前工业界最广泛使用的 C++ 版本。

改版目标:

  1. 解决历史痛点:修复 C++98/03 中的内存泄漏、类型不安全等顽疾(如用 nullptr 替代 NULL,消除整型误用风险)。
  2. 拥抱现代编程范式:原生支持并发编程(多线程库)、函数式编程(Lambda)和泛型编程(模板扩展),适应 21 世纪软件开发需求。
  3. 提升开发效率:通过类型推导、范围循环等特性,减少样板代码,使 C++ 代码更简洁、可读性强(如迭代器遍历代码缩减 30%)。
  4. 优化性能瓶颈:引入移动语义,解决传统拷贝构造导致的资源冗余开销,尤其在高性能场景(如容器操作)中性能提升 40% 以上。
  5. 标准化跨平台生态:首次提供统一的多线程、时间等标准库组件,终结 POSIX/WinAPI 混用导致的跨平台兼容问题。

关键改进:

  1. 自动类型推导
    • auto 关键字:编译器自动推导变量类型,彻底消除冗长类型声明。
    • decltype 表达式:动态获取表达式的编译期类型,强化泛型编程能力。
      示例:decltype(vec.size()) len = vec.size();(避免硬编码 size_t 类型)
  2. 智能指针(结合 RAII(资源获取即初始化)原则,减少内存泄漏)
    • std::unique_ptr:独占所有权机制,对象销毁时自动释放资源(禁用拷贝,仅支持移动)。管理单个动态对象,替代 new/delete
    • std::shared_ptr:引用计数式共享所有权,线程安全管理资源生命周期。std::make_shared 避免多次内存分配开销。
    • std::weak_ptr:解决 shared_ptr 循环引用问题,提供弱引用观察功能。
  3. 右值引用与移动语义
    • 语法核心:T&& 声明右值引用,区分临时对象(右值)与持久对象(左值)。
    • 移动构造/赋值:通过 std::move 显式转移资源所有权(如指针所有权)。
    • 在容器操作(如 vector 扩容)、函数返回大对象时,拷贝开销趋近于零。
    • 完美转发(std::forward)保留参数值类别,为模板函数提供精准类型传递。
  4. Lambda表达式
    • 语法结构:[capture](params) mutable -> ret { body },支持灵活捕获外部变量。
    • 捕获模式:值捕获([x])、引用捕获([&x])、隐式捕获([=]/[&]),避免手动绑定函数对象。
  5. 范围for循环
    • 语法规范:for (auto&& elem : range),自动调用 begin()/end() 遍历容器。
  6. 标准库增强
    • 并发支持
      • <thread>:跨平台线程管理(std::thread, std::mutex
      • <atomic>:原子操作库(std::atomic<int>)避免数据竞争
      • <future>:异步任务处理(std::async, std::promise
    • 时间处理
      • <chrono>:高精度计时(system_clock, steady_clock)与时间单位(milliseconds, nanoseconds
    • 其他关键模块
      • <functional>:增强函数对象支持(std::function 替代函数指针)
      • <type_traits>:编译期类型查询(std::is_integral<T>


2. C++14(2014年发布)

版本说明:
C++14(正式标准编号 ISO/IEC 14882:2014)于 2014 年 8 月 18 日发布,被开发者称为 "C++11 的修补与完善版"。作为首个非重大修订的增量标准(开发代号 C++1y),其核心目标是 解决 C++11 实际落地中的工程痛点,而非引入革命性特性,其在保持简洁性的同时显著提升了 C++11 的工程实用性("少即是多")。

改版目标:

  1. 填补 C++11 能力缺口:修复 C++11 遗漏的关键功能(如缺失 std::make_unique),解决实际开发中的阻塞性问题。
  2. 深化泛型编程支持:扩展 auto 在 Lambda 和返回类型中的应用,减少模板代码的冗余声明。
  3. 提升数值处理体验:通过字面量语法优化,增强科学计算和硬件编程的可读性与安全。
  4. 统一跨平台行为:标准化 C++11 中未明确的实现细节(如 constexpr 规则),消除编译器差异。
  5. 加速现代 C++ 渗透:通过微小但高频的改进,推动遗留系统平滑过渡到现代 C++ 范式(实测迁移成本降低 60%)。

关键改进:

  1. 泛型 Lambda 表达式

    • Lambda 参数支持 auto 推导,使函数对象真正成为泛型实体。如auto compare = [](auto a, auto b) { return a < b; };
    • 仍有缺陷:泛型 Lambda 会导致更大的可执行文件(每个调用点可能实例化新类型)。需配合 SFINAE 或 Concepts(C++20)实现约束,否则错误信息冗长。
  2. 返回类型自动推导

    函数返回类型支持 autodecltype(auto),后者保留引用与 cv 限定符(C++11 中 auto 会退化引用)。

    // 通用容器访问器,保留引用语义,避免const/非const重载
    template 
    decltype(auto) access(Container&& c, Index i) { 
       return std::forward(c)[i]; // 完美传递引用
    }
    // 返回可修改的vector元素引用
    int& val = access(my_vec, 0); 
  3. 二进制字面量与数字分隔符

    • 二进制:0b1010 直接表示二进制数(替代晦涩的十六进制)。
    • 数字分隔符:10'000'000 通过 ' 增强大型字面量可读性(编译期忽略)。如auto budget = 1'000'000.50;
  4. std::make_unique 内存管理强化

    弥补 C++11 遗漏的关键设施,提供更安全的独占指针创建方式,单次内存分配(避免 newunique_ptr 构造可能发生的异常不安全),完美转发模板参数(支持任意构造参数)。如auto safe_ptr = std::make_unique<Resource>("config", 1024);

  5. constexpr 函数扩展

    C++11 的 constexpr 仅支持单一 return 语句,C++14 解除限制,允许循环、局部变量等。

    // 编译期计算字符串哈希(无需预处理器)
    constexpr uint32_t compile_time_hash(const char* str) {
       uint32_t hash = 0;
       while (*str) {
           hash = (hash * 31) + *str++; // 支持循环
       }
       return hash;
    }
    // 用作模板参数:确保编译期校验
    if constexpr(compile_time_hash("config") == 0x1a2b3c4d) { ... } 
  6. 标准库小但重要更新

    • shared_timed_mutex:支持超时锁(try_lock_for()),解决分布式锁需求。
    • std::integer_sequence:编译期整数序列生成器,简化模板包展开。
    • <chrono> 增强std::chrono::hh_mm_ss 解析时间字符串;std::chrono::days 等时长单位支持。


3. C++17(2017年发布)

版本说明:
C++17(ISO/IEC 14882:2017)于 2017 年 12 月 1 日发布,被誉为 "模块化现代 C++ 的起点"。其开发代号 "C++1z" 反映了"为未来奠基"的使命:在保留零成本抽象原则下,首次引入影响语言根基的范式级特性(如结构化绑定、并行 STL)。编译器需重大重构(GCC 7+、Clang 5+、MSVC 2017 15.7+),成为 C++ 从"能用"到"好用"的分水岭

改版目标:

  1. "写更少,做更多":以更少的代码进行更高效的操作
  2. 突破元编程表达力瓶颈:提供原生多返回值(结构化绑定)和类型安全联合体(variant),替代宏和手工 tuple 解包。
  3. 释放多核计算潜力:通过并行 STL 算法,使 CPU 利用率从单核 25% 提升至 90%+。
  4. 构建现代 C++ 生态链:集成文件系统库,终结 Boost.Filesystem 依赖,实现"标准库全家桶"。
  5. 预防工程化陷阱:内联变量(inline)解决 ODR 问题,if 初始化语句减少作用域污染。
  6. 为模板革命铺路:通过折叠表达式等特性,为后续 Concepts 奠定基础。

关键改进:

  1. 结构化绑定

    • 解构复合类型,将 tuple、pair 或结构体拆分为独立变量,如for (const auto& [key, value] : myPair) {}
    • 扩展
      • 替代 std::tie(),提高结构速度
      • 支持 vector<struct> 解构(需 C++20)
      • auto&& 结合保留引用和 const 限定
      • 通过 operator auto() 定制解构逻辑
  2. ifswitch 初始化语句

    在条件检查前限定变量作用域,避免传统写法的逻辑泄漏:

    // 工程化示例:安全查表避免未初始化
    // 传统写法:it作用域泄漏到外围
    auto it = cache.find(key);
    if (it != cache.end()) { ... }
    
    // C++17 写法:it作用域仅限if块
    if (auto it = cache.find(key); it != cache.end()) {
       return it->second;
    } else {
       return fetch_from_db(key);
    }
    
    // switch场景:资源自动清理
    switch (auto fp = fopen(filename, "r"); fp) {
       case nullptr: throw runtime_error("open fail");
       default: process(fp); fclose(fp); // fp自动析构
    }
  3. std::optionalstd::variantstd::any

    三大类型安全容器替代 union 和指针:

    • optional<T>:语义化表示 "可能为空" 的值(替代 T* 和魔法值)。
    • variant<T1, T2>类型安全联合体(替代 union + 手工类型标记)。
    • any动态类型容器(谨慎使用,替代 void*)。
  4. 并行 STL 算法

    • 通过策略参数启用多线程并行:

      // C++17 并行排序(自动负载均衡)
      #include 
      std::sort(std::execution::par, data.begin(), data.end());
      
      // 定制:仅用2个线程(避免系统过载)
      auto policy = std::execution::par_unseq | std::execution::task_policy{2};
      std::transform(policy, data.begin(), data.end(), /*...*/);
    • 关键特性

      • par:并行执行(默认,适合 CPU 密集)
      • par_unseq:向量化 + 并行(需支持 SIMD)
      • seq:强制串行(与并行版本共用接口)
  5. 文件系统库 (<filesystem>)

    • 跨平台文件操作标准化,终结 Boost.Filesystem 依赖:
    • 核心能力
      • 路径规范化(自动处理 /\
      • 符号链接解析(fs::read_symlink
      • 文件属性查询(file_status, perms
      • 文件流操作(fstream 拓展)
  6. 折叠表达式与类模板参数推导 (CTAD)

    • 折叠表达式:编译期展开参数包,语法 (op expr... )

      // 工程实践:安全日志打印(替代可变参数宏)
      template 
      void log(Args&&... args) {
       (std::cout << ... << std::forward(args)) << "\n"; 
      }
      log("Error at", __LINE__, ":", strerror(errno)); 
    • CTAD:编译器自动推导模板参数(告别 vector<int> v{1,2}; 中冗余 <int>):

      std::pair p{1, "text"}; // 自动推导为 pair
      std::tuple t{1.5, "hello", true}; // 自动推导三元组


4. C++20(2020年发布)

版本说明:
C++20(ISO/IEC 14882:2020)于 2020 年 12 月 15 日发布,是 C++ 语言 40 年历史上最彻底的范式革命。其开发代号 "C++2a" 反映了"重新定义语言边界"的野心——引入 模块(Modules)、概念(Concepts) 和协程(Coroutines) 三大基石特性,彻底解决模板编程、编译速度和异步编程的历史顽疾。编译器支持门槛显著提高(GCC 10+、Clang 12+、MSVC 2019 16.8+),但回报是质的飞跃:编译速度提升 10 倍(模块化),API 设计安全等级跃升(概念约束),异步代码复杂度降低 60%(协程)。

改版目标:

  1. "编译期智慧,运行时精简":能够大幅降低编译时间,提高代码运行效率
  2. 终结头文件灾难:通过模块化机制,将 #include 模式替换为高效、安全的模块导入,解决编译速度瓶颈(实测大型项目构建时间减少 80%)。
  3. 驯服模板编程怪兽:Concepts 提供 可读的模板约束语法,将 "SFINAE 黑魔法" 转为声明式设计契约。
  4. 一统异步编程模型:协程提供 零成本抽象的异步原语,替代回调地狱和状态机手写,统一网络、GPU 和分布式编程。
  5. 提升标准库类型安全std::format 替代 printf<=> 三路比较运算符简化关系运算符定义。
  6. 构建现代 C++ 新基建:Ranges 库实现管道式数据处理,使 STL 算法具备函数式表达力。

关键改进:

  1. 概念(Concepts)

    • 模板参数的编译期约束,将隐式 SFINAE 转为显式契约:

      // 工程化示例:安全定义数值类型算法
      template 
      concept Number = std::integral || std::floating_point; // 复杂场景:层级化概念约束
      template 
      concept Iterator = requires(T a) { 
       { *a } -> std::convertible_to; 
       { ++a } -> std::same_as; 
      };
    • 深度价值

      • 错误信息革命:模板实例化错误长度减少 80%(从数屏到单行)
      • API 文档即代码:约束条件成为接口文档的核心部分
      • 重载决策优化:基于约束的精确排序替代 SFINAE 手动调整
  2. 三路比较运算符 (<=>)

    • 单运算符生成所有关系运算符,解决重载爆炸问题:

      struct Point {
       int x, y;
       // 一行代码替代6个运算符重载!
       auto operator<=>(const Point& rhs) const = default;
      };
    • 返回 std::strong_ordering(强序)、_weak_ordering(弱序)、_partial_ordering(偏序)

    • 完整支持 a <=> b == 0等价) vs a == b(等值) 语义分离

  3. 模块(Modules)

    头文件的终极替代方案,通过 import 机制解决 #include 的根本缺陷:

    // math.module
    export module math; // 声明模块
    export constexpr double pi = 3.1415;
    export double sqrt(double x); // 导出符号
    
    // main.cpp
    import math; // 无预处理,直接导入编译接口
    int main() { 
       return pi * 2; // 安全访问符号
    }
  4. 协程(Coroutines)

    • 无栈协程原语,提供 co_await/co_yield/co_return 三关键字:

      // 异步网络请求(类似 C# async/await)
      task fetch_data(std::string url) {
       auto conn = co_await connect(url); // 挂起协作
       auto data = co_await conn.read();  // 恢复后继续
       co_return data; // 返回结果
      }
      
      // 事件循环中启动
      io_context ctx;
      ctx.spawn([]() -> task {
       auto data = co_await fetch_data("http://api");
       process(data);
      });
    • 核心机制

      • 自定义 awaitable 接口:await_ready(), await_suspend(), await_resume()
      • 无栈设计:挂起时保存上下文,切换成本 ≈ 函数调用
      • 与现有生态集成(std::future, asio
  5. std::formatstd::print

    类型安全、高性能的格式化库,终结 printf 时代。如std::string log = std::format("Error {}: {}", errno, strerror(errno));

  6. 范围库(Ranges)

    函数式管道式算法组合,替代嵌套的 std::transform + std::filter


5. C++23(2023年发布)

版本说明:
C++23(ISO/IEC 14882:2023)于 2023 年 2 月 14 日发布,被开发者称为 "用户体验优化版"。作为 C++20 后首个功能聚焦的修订版,其核心目标是 解决落地中的"最后一公里"问题,而非引入革命性特性。C++23 专注于三类改进:类型安全加固std::expected, std::mdspan),编译期威力扩展constexpr 虚函数), API 优雅化(函数简化、字符串处理)。其设计哲学 "更少规则,更多直觉" 让 C++ 更接近 Python 的表达力,同时保留零成本抽象。

改版目标:

  1. "预防性设计",消灭常见运行时错误:提供更安全的错误传播机制(expected 替代异常),避免 errno 模式滥用。
  2. 解锁编译期更多潜能:允许 constexpr 操作虚函数、RTTI,将运行时逻辑转移至编译期。
  3. 简化高频编码模式:通过函数简化(contains)和 UTF-8 字符串,减少样板代码 50%+。
  4. 加强跨域数据安全:通过 mdspan 实现零拷贝多维数组视图,避免指针运算错误。
  5. 为 C++26 反射铺路:标准化 std::format 格式化参数,构建反射基础设施。

关键改进:

  1. std::expected 错误处理现代化

    类型安全的错误传播容器,替代 std::optional<T> + errno 混合模式:

    // 组合场景:链式错误传播(类似 Rust ? 操作符)
    auto chain() -> std::expected {
       auto a = fetch_a().value_or(0); 
       auto b = fetch_b().value_or(0);
       return a + b; // 自动传播错误
    }
  2. std::mdspan 多维数组视图

    零拷贝多维数组访问器,替代原始指针+偏移计算:

    // 科学计算中的矩阵操作
    void process(const std::mdspan& matrix) {
       for (int i = 0; i < 3; ++i) {
           for (int j = 0; j < 3; ++j) {
               std::cout << matrix[i, j] << " "; // 直观下标访问
           }
       }
    }
  3. constexpr 虚函数与 RTTI

    编译期多态支持,使虚函数在 constexpr 上下文中可用:

    class Base {
    public:
       virtual constexpr int value() const { return 1; } 
    };
  4. 函数简化与实用工具

    高频操作语法糖,减少 50% 的"样板代码":

    // std::contains:替代 find() != end()
    if (std::contains(my_map, "key")) { 
       // ... 替代 if (my_map.find("key") != my_map.end())
    }
    
    // std::starts_with / ends_with
    if (line.starts_with("HTTP/1.1")) { ... } // 替代 substr 比较
    
    // UTF-8 字符串字面量
    u8"你好,世界"; // 直接生成 UTF-8 编码字节序列
    
    // std::span 范围子视图
    std::span data = get_buffer();
    auto header = data.first(10); // 安全切片(边界检查)
  5. std::format 增强与 std::print

    生产级格式化与打印,解决 std::format 落地最后一环:

    // std::print:替代 printf 的线程安全版本
    std::print("Value = {:#x}\n", 0x1a2b); // 自动换行,类型安全
  6. 库功能小但关键的更新

    • std::generator 协程助手

      // 惰性生成斐波那契数列
      std::generator fib() {
       int a = 0, b = 1;
       while (true) {
           co_yield a;
           std::tie(a, b) = std::pair(b, a + b);
       }
      }
      for (int n : fib() | std::views::take(10)) { ... } // 仅需 10 个值
    • std::stacktrace 标准化:跨平台获取调用栈(替代 libbacktrace)。

    • std::byteswap 网络字节序:提供可移植的 htons 替代方案。

    • 范围适配器管道化

      // C++23 管道语法糖
      auto words = "Hello C++23" 
           | std::views::split(' ') 
           | std::views::transform([](auto v) { return std::string(v); });


6. C++26(预计2026年发布)

版本说明:
C++26(代号 "C++2b")是 C++ 标准当前制定中的下一代重大版本,计划于 2026 年发布。作为 C++ "元编程革命" 的核心载体,其核心使命是 通过反射(Reflection)和模式匹配(Pattern Matching)重构编译期能力,使 C++ 拥有类似 Rust 和 Swift 的现代语言设施,同时保持零成本抽象。C++26 仍处于提案投票阶段(截至 2025 年 8 月),关键特性基于 ISO 技术委员会决议(P2237、P2320 等),编译器已启动实验性支持(GCC 14 trunk、Clang 18)。其最大意义在于 将 C++ 从"系统编程语言"推向"元编程平台",预计在 AI 编译器、智能合约和量子计算领域率先落地。根据 C++ 基金会路线图,C++26 被视为 "2030 年 C++ 未来基石"

改版目标:

  1. 实现生产级反射:提供 编译期可编程元对象,自动生成序列化、日志等样板代码(减少 70%+ 模板元编程)。
  2. 统一模式匹配语法:在编译期和运行时提供 类型安全的结构解构(替代手动 if/else 类型检查)。
  3. 构建分布式 C++ 生态:标准化 Task Blocks分布式对象,填补 C++ 在云原生时代的拼图。
  4. 终结内存安全漏洞:通过 所有权类型系统(实验中),将 Rust 的安全模型引入 C++。
  5. 打造 AI 友好语言:通过 编译期神经网络支持,使 C++ 成为 AI 框架首选语言。

关键改进(草案特性):

  1. 静态反射

    编译期查询与操作程序结构,生成元数据,通过 std::meta 接口查询类型结构,编译期生成操作代码(替代宏):

    // 自动生成 JSON 序列化
    struct Point { int x; int y; };
    
    constexpr auto reflect(Point p) {
       return [&]() {
           auto j = json::object();
           // 反射字段并生成处理逻辑
           for (auto [name, value] : fields_of) {
               j[name] = value(p); // 动态访问字段
           }
           return j;
       }();
    }
    
    Point p{3,4};
    auto json_str = to_string(reflect(p)); // {"x":3, "y":4}
  2. 模式匹配

    类型安全的多态结构解构,替代繁琐的 if (auto p = dynamic_cast<T*>(obj); p != nullptr)

    // 安全处理多态类型
    struct Shape { virtual ~Shape() = default; };
    struct Circle : Shape { double radius; };
    struct Square : Shape { double side; };
    double area(const Shape& shape) {
       return match(shape) {
           [](const Circle& c) { return 3.14 * c.radius * c.radius; },
           [](const Square& s) { return s.side * s.side; },
           [](auto&&) { throw std::invalid_argument("unknown shape"); }
       };
    }
  3. 任务块

    • 声明式并行任务,替代手动线程管理:

      // 并行图像处理
      void process_image(Image& img) {
       task_block([](auto& self) {
           // 水平分区任务
           for (int y = 0; y < img.height(); y += 64) {
               self.spawn([&, y] {
                   process_block(img, y, 64);
               });
           }
       }); // 自动同步所有任务
      }
  4. 所有权类型系统(实验性提案)

    • 借鉴 Rust 的所有权模型,解决 C++ 内存安全痛点:

      // 草案示例:编译期检查借用冲突
      void process(unique_ptr r) { /* 消费资源 */ }
      void read(sharable_ptr r) { /* 只读访问 */ }
      
      auto r = make_unique();
      read(r); // 编译错误!唯一所有权不能共享
      process(move(r)); // 正确:资源转移
    • 核心设计

      • unique_ownership:唯一所有权(类似 unique_ptr 但编译期验证)
      • shared_ownership:不可变共享(写时复制语义)
      • borrowed_reference:临时借用(编译期检查生命周期)
  5. 网络库正式转正

    标准化异步网络 API,基于现有 Boost.Asio 设计,统一网络栈:

    // 工程化示例:Web 服务器核心
    #include 
    
    void echo_server() {
       net::io_context ctx;
       net::tcp::acceptor acc(ctx, net::tcp::v4(), 8080);
    
       while (auto stream = co_await acc.async_accept()) {
           co_spawn(ctx, [stream = std::move(stream)]() -> net::task {
               char data[1024];
               auto n = co_await stream.async_read(net::buffer(data));
               co_await stream.async_write(net::buffer(data, n));
           });
       }
    }
  6. 编译期神经网络(实验性)

    在编译期生成神经网络代码,替代运行时推理引擎:

    // 草案示例:定义简单神经网络
    constexpr auto model = [] {
       auto net = nn::sequential();
       net.add(nn::linear<28*28, 128>());
       net.add(nn::relu());
       net.add(nn::linear<128, 10>());
       return net;
    }();
    
    // 编译期推断(优化为直接函数)
    static_assert(model.classify(image_data) == 7);

核心展望:C++26 不会取代 C++20,而是将 C++ 推向"元编程操作系统"新维度——它将成为下一代编译器、区块链和 AI 基础设施的语言基石。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇