C++ STL 之 optional、variant 与 any 详解

C++17:std::variant/std::optional/std::any设计 文章目录前言稍微总结std::variant动机和设计内部实现boostSTLstd::optional动机和设计内部实现boostSTLstd::any动机和设计转换内部实现boostSTL 前言 2021年了。现在回顾一下c++17标准中的std::variant/std::optional/std::any三个库是怎么实现的。 稍微总结 这三个库基本都是实现可选语义: std::optional:存有T或者不存有值 std::any:存有任意类型值(可以看作带类型信息的void*) std::var 阅读详情

C++ STL 之 optional、variant 与 any 详解

一、问题

C++ 类型系统在 C++17 之前有三大短板:

  • 函数返回值无法优雅表达"可能无值"——传统做法用指针(可能空悬)或哨兵值(如 -1、nullptr),语义含混且易误用
  • 需要"要么 A 要么 B"的类型安全变体——只能用 union,但原始 union 不检查活跃成员,读取错误成员属于未定义行为
  • 需要持有任意类型的值(完全的动态类型)——过去只能退化为 void* + 手动 RTTI,或继承方案

C++17 引入的 std::optional、std::variant、std::any 分别补上了这三个短板。

二、optional:可能无值的语义

2.1 基本用法

#include <optional>
#include <iostream>
#include <string>

std::optional<int> parse_int(const std::string& s) {
    try {
        return std::stoi(s);
    } catch (...) {
        return std::nullopt;  // 无值
    }
}

int main() {
    auto r1 = parse_int("42");
    auto r2 = parse_int("abc");

    // has_value
    std::cout << r1.has_value();      // 1
    std::cout << r2.has_value();      // 0

    // value_or 提供默认值
    int v = r2.value_or(-1);          // -1

    // operator* / operator->(没有安全检查,需自己保证 has_value)
    if (r1) {
        std::cout << *r1;             // 42
    }

    // value() 会抛 bad_optional_access
    // r2.value();  // 抛异常
}

2.2 注意事项

  • optional<T> 会存储额外的 bool 标记,如果 T 自身可以被默认构造为"空"状态(如 std::string),不一定比哨兵值更省
  • optional<T&> 是 C++17 不支持的(C++23 才引入),引用包装推荐用 std::reference_wrapper 或裸指针
  • value_or 的参数是按值传入的,即使 T 是移动成本高的类型也会拷贝,注意用 std::move 或手动短路 if(opt)

三、variant:类型安全的联合体

3.1 基本用法

#include <variant>
#include <string>
#include <iostream>

// 定义一个 "要么 int 要么 string" 的类型
std::variant<int, std::string> v = 42;

// 赋值另一个类型
v = "hello";

// 获取值——类型不匹配时抛 bad_variant_access
int i = std::get<int>(v);      // 抛异常,当前是 string
std::string s = std::get<std::string>(v);  // OK

// get_if 返回指针,失败返回 nullptr
if (auto* p = std::get_if<int>(&v)) {
    std::cout << *p;
} else {
    std::cout << "不是 int";
}

3.2 std::visit:编译期分派

std::visit 是 variant 的核心武器——它根据 variant 当前活跃的索引,在编译期生成所有分支的分派表,运行时只需查偏移:

auto visitor = [](auto&& arg) {
    using T = std::decay_t<decltype(arg)>;
    if constexpr (std::is_same_v<T, int>)
        std::cout << "int: " << arg;
    else if constexpr (std::is_same_v<T, std::string>)
        std::cout << "string: " << arg;
};

std::visit(visitor, v);  // 编译期分派,零虚函数开销

对比虚函数方案:std::visit 的分派时间与 variant 的备选类型数量是 O(1) 的(查索引跳转表),而虚函数需要一次虚表查址加一次间接调用。两种都很便宜,但 visit 不需要类层次继承,组合更灵活。

3.3 variant vs 传统 union

读 a

读 b

是

否

union 声明

赋值成员 a

读取哪个成员?

正确

未定义行为

程序员自行
跟踪活跃成员

variant 声明

赋值 string

get?

抛 bad_variant_access

get 成功

编译期类型安全

3.4 注意事项

  • variant 的默认构造会构造第一个类型的默认值,如果第一个类型不可默认构造,variant 也不能默认构造。可以用 std::monostate 作为第一备选来做"空"语义
  • 访问不活跃成员抛异常:std::get 抛 std::bad_variant_access,std::get_if 返回 nullptr
  • valueless_by_exception():赋值时如果异常发生,variant 可能进入无值状态,一般情况下应避免让其进入此态

四、any:类型擦除的通用容器

4.1 基本用法

#include <any>
#include <iostream>
#include <string>

std::any a = 42;               // 存 int
a = std::string("hello");      // 存 string
a = 3.14;                      // 存 double

// 取出时必须类型完全一致
try {
    double d = std::any_cast<double>(a);  // OK
    int i = std::any_cast<int>(a);        // 抛 bad_any_cast
} catch (const std::bad_any_cast& e) {
    std::cout << e.what();
}

// any_cast 指针版本,失败返回 nullptr
if (auto* p = std::any_cast<double>(&a)) {
    std::cout << *p;
}

4.2 性能代价

std::any 的实现内部做两次动态分配(堆 + 类型擦除包装器):

  1. 对于小对象(通常 ≤ 32 字节且可平凡拷贝),实现可能用 SBO(小对象优化)避免堆分配,但不可平凡拷贝的大对象一定堆分配
  2. 每次 std::any_cast<T> 内部通过 typeid 比较运行时类型信息(RTTI),有运行时代价
  3. 与 optional(零堆分配)和 variant(栈上存储 + 编译期)相比,any 是最重的方案

结论:除非必须持有运行时才能确定的任意类型,否则优先用 optional 或 variant。

五、选型指南

是

否

是

否

是

否

场景:需要持有
什么类型的值?

运行时类型
完全已知?

可能无值?

std::any

std::optional

类型数量
有限且已知?

std::variant

语义:可能有值也可能没有
例:解析结果、查找返回值

语义:固定几个类型中的某一个
例:AST 节点、消息类型

语义:运行时才能确定的任意类型
例:插件系统、序列化反序列化

六、面试题

Q1:optional<T> 和裸指针有什么区别?

A:裸指针可以表达空(nullptr)但有歧义——它是"没有值"还是"指向的对象被销毁"?optional 语义明确,且支持 value_or、has_value、and_then(C++23)等组合子,不可空悬。

Q2:optional<T> 的空间开销是多少?

A:额外一个 bool(通常 1 字节 + padding),对齐由 T 决定。如果 T 自身有"空"状态(如 std::string 的空字符串),optional 并不比带哨兵的版本省空间,但语义更清晰。

Q3:std::visit 比虚函数快吗?

A:实测两者在同一量级。std::visit 通过索引跳转表 O(1) 分派,但编译器倾向于把虚函数内联。关键区别在组合:variant + visit 不需要类层次,新增类型只需扩展 variant 类型参数,不侵入已有代码。

Q4:variant 的空状态是怎么回事?

A:默认构造构造第一个类型;如果赋值时发生异常,variant 可能进入 valueless_by_exception() 为 true 的状态,此时任何 get 和 visit 都会抛异常。可以用 std::monostate 作为第一类型(占位 0 字节)来手动管理空状态。

Q5:std::any 为什么比 variant 慢?

A:因为 any 做类型擦除用到虚函数包装器和堆分配,且 any_cast 依赖 typeid 运行时比较;variant 的所有备选类型编译期已知,存储在栈上,分派是编译期构造的索引表。

Q6:请用合适的工具实现一个能存 int、double、string 之一的类型,应选 variant 还是 any?为什么?

A:选 variant<int, double, string>。因为类型集合编译期完全确定,variant 零堆分配、O(1) 分派、类型安全。any 会引入不必要的动态分配和 RTTI 查询。

Q7:optional、variant、any 能否组合使用?

A:可以。例如 optional<variant<int, string>> 表示"要么没有值,要么是 int 或 string";variant<int, any> 可以表达"已知 int 或其类型未知的"——但后者在实践中很少用,因为 any 已经包揽了"任意"语义。

现代C++编程指南:C++17与C++20核心特性解析与实践 C++作为一门高性能系统编程语言,其核心价值在于提供对硬件资源的精细控制与零成本抽象。随着现代软件开发对代码安全性、可维护性和开发效率的要求不断提升,C++标准委员会通过引入新特性来优化语言设计,降低常见错误风险。从语言原理层面看,现代C++通过RAII(资源获取即初始化)等机制实现自动资源管理,利用模板元编程和编译期计算提升运行时性能。这些技术演进的实际价值体现在能够构建更健壮、更易维护的大型软件系统,特别是在高性能计算、游戏引擎、基础设施软件等场景中。本文聚焦于C++17和C++20两个重要版本,深入解 阅读详情

相关推荐

C++ STL核心组件与算法实战:从容器选型到现代C++最佳实践

在C++编程中,数据结构和算法是构建高效软件的基础。STL(Standard Template Library)作为C++标准库的核心,通过泛型编程思想,提供了一套经过高度优化的通用组件库,其价值在于提升代码的抽象层次、复用性和安全性。STL的核心设计基于三大组件:容器用于存储数据,算法用于操作数据,迭代器则作为连接两者的桥梁。理解不同容器的底层实现(如vector的连续内存、map的红黑树、unordered_map的哈希表)及其时间复杂度特性,是进行技术选型的关键。在实际工程中,结合移动语义、完美转发等

weixin_33922672的博客 316

系统性掌握C++17容器四件套:std::optional, std::any, std::variant, std::tuple

许多开发者分不清std::variant和std::any之间的区别,于是萌发了写一篇文章系统性介绍一下C++中这类容器的想法。

hebhljdx的博客 1670

使用STL官方Natvis文件提升Visual Studio C++调试效率

在C++开发中,调试是定位和解决问题的关键环节。调试器通过读取程序内存和调试符号来展示变量信息,但对于STL容器等复杂数据结构,默认视图往往显示为难以理解的内存布局和内部成员变量。Natvis技术通过XML配置文件为调试器提供类型可视化规则,将内存布局转换为逻辑视图,从而显著提升调试效率。其核心价值在于让开发者能够直观地观察数据结构内容,而非解析底层实现细节。在工程实践中,STL官方维护的natvis文件与编译器版本完全同步,能准确匹配std::vector、std::map等容器的内部实现,覆盖边界情况和

chuliaoqiao4046的博客 526

【C++】一篇文章详解C++17新特性

C++17引入了多项提升开发效率的特性,主要包括语法糖和STL容器扩展。语法糖方面,if-else初始化语句允许在条件判断前声明临时变量,结构化绑定简化了多变量提取操作,折叠表达式优化了可变参数模板的处理。STL容器新增了std::optional(可选值)、std::variant(类型安全联合体)和std::any(任意类型容器),解决了空值处理和多类型存储问题,使代码更安全简洁。这些改进显著减少了样板代码,提高了类型安全性和开发效率,是C++现代化开发的重要里程碑。

2402_88083295的博客 928

现代C++新特性全景解析:从C++11到C++20的核心演进与实战指南

C++作为一门历经数十年发展的系统级编程语言,其核心价值在于提供高性能、资源可控的底层编程能力。随着软件工程复杂度的提升,语言本身也在不断演进,从C++98/03的经典范式,到C++11引入的现代化特性,其演进逻辑始终围绕提升开发效率、增强类型安全、优化运行时性能三大目标。理解这一演进脉络,对于掌握现代C++编程范式至关重要。C++11的智能指针通过RAII机制解决了手动内存管理的核心痛点,右值引用与移动语义则从语言层面优化了对象拷贝性能,这些特性共同构成了现代C++的基石。后续版本如C++14/17的泛型

weixin_30247781的博客 394

[c++17] --- c++17相对于c++11的新增特性

C++11引入了许多现代C++特性,例如lambda表达式、自动类型推导、智能指针、移动语义、constexpr等。这些特性使得C++更加现代化、简洁、高效、安全,而C++17在C++11的基础上继续引入了一些新的特性和改进,例如结构化绑定、if constexpr、内联变量、类模板参数推导、并行算法等,进一步提高了C++的开发效率和代码质量。 Note: 本专栏默认读者已了解c++11新特性,通过对比c++11,总结c++17新特性。

M2嵌入式 1200

C++17核心特性实战解析:结构化绑定、optional与编译期编程

现代C++编程中,类型安全和代码简洁性是提升工程效率的关键。通过编译期计算和零成本抽象,开发者可以在不牺牲性能的前提下增强代码表达力。C++17引入的结构化绑定机制,允许直接从复合类型中解包数据,配合auto类型推导,显著简化了容器遍历和多重返回值处理。std::optional和std::variant等类型安全工具,解决了传统错误处理和联合体使用的痛点,通过编译期类型检查降低运行时风险。这些特性在系统开发、游戏引擎和高频交易等场景中,能够帮助开发者用更清晰的意图表达业务逻辑,同时减少低级错误。本文聚焦结

weixin_34279246的博客 489

重学C++17 STL:六大新组件与并行算法实战指南

C++标准库的每次演进都深刻影响着工程实践。C++17在STL层面引入了string_view、optional、variant、filesystem及并行算法等关键组件,解决了长期依赖第三方库或手写实现的痛点。string_view通过零拷贝字符串视图优化函数传参性能;optional用类型系统表达“可能失败”的返回值;variant提供了类型安全的联合体替代方案;filesystem统一了跨平台路径操作。同时,带执行策略的并行算法让sort、transform等操作天然支持多核加速。这些新特性不仅提升了

weixin_30219613的博客 233

C++ STL 实用函数用法介绍(std::forward, std::bind, std::optional, std::any, std::variant, std::ref等)

又称转发引用,能够在参数类型推导过程中适当将其转化为右值引用,另外std::forward和变长模板结合使用可实现完全泛型函数,即函数模板可以接受任意数量的参数,并在不改变参数的情况下转发它们)2. std::lerp(a, b, t) 是计算a,b两个数的线性算术运算,返回值为 a + t*(b - a)1:将a资源移到b资源中,完成后a资源将处于未定义状态,如果无法应用移动语义,则执行拷贝操作。1. std::midpoint(a, b) 是计算a,b中点;(注意该函数模板参数必须是。

GPU全栈博主 552

QEMU+KVM实战:5分钟搞定Ubuntu 24.04虚拟机搭建(附性能优化技巧)

本文详细介绍了在Linux宿主机上使用QEMU和KVM快速搭建Ubuntu 24.04虚拟机的完整实战流程。内容涵盖从环境准备、核心组件解析到具体的安装命令,并重点分享了针对CPU、内存、存储I/O及网络性能的深度优化技巧,旨在帮助用户构建一个响应迅速、资源隔离良好的高性能虚拟化开发与测试环境。

j2k3l4的博客 753

LLM and Embedding区别

LLM(大语言模型)和 Embedding(嵌入)是自然语言处理(NLP)中的两个核心概念,它们的核心区别在于。Embedding 计算向量。

u010674101的专栏 1874

C++17 STL实战指南:新特性解析与现代C++编程实践

C++标准模板库(STL)作为C++编程的核心组件,通过提供泛型容器、算法和迭代器等基础设施,极大地提升了代码的复用性和开发效率。其设计原理基于泛型编程思想,通过模板技术实现类型安全的抽象,使得开发者能够编写高效且通用的代码。在C++17标准中,STL迎来了多项重要增强,这些新特性不仅提升了代码的表达能力,还显著改善了性能与安全性。例如,std::optional为处理可能缺失的值提供了类型安全的解决方案,而std::string_view则通过非拥有式字符串视图实现了零成本的字符串操作,有效优化了性能。这

weixin_31315567的博客 347

基于Landsat-8数据的山西省吕梁市地表温度反演研究过程(大气校正法)

1.数据下载:本实验采用的数据是 ①从地理空间数据云下载的来自landsat8 卫星,云量<=1%,时间为2017年5月12日的山西省吕梁市影像数据。为全面覆盖吕梁市,选用了两片影像。 ②吕梁市边界矢量图 2.数据预处理 ...

weixin_45747376的博客 6601

C++模板与STL:从泛型编程到高效容器算法的实战指南

泛型编程是C++实现代码复用和类型安全的核心范式,其原理在于通过模板将数据类型参数化,编译器在编译时根据具体类型生成特化代码。这一技术价值在于显著提升开发效率与代码可维护性,避免了为不同数据类型重复编写相似逻辑。在工程实践中,标准模板库(STL)基于泛型编程提供了工业级的数据结构与算法组件,例如vector、map和sort等,广泛应用于需要高性能容器和通用算法的场景,如游戏开发、算法竞赛和系统软件中。本文聚焦于C++模板机制与STL的深度解析,涵盖迭代器、容器选择策略及现代C++特性,帮助开发者掌握构建健

weixin_30905133的博客 316

AI产品经理必备:Agent评测维度、指标与工程化落地指南

随着大模型从单轮问答走向复杂的Agent应用,如何科学地评测一个Agent是否真正“办成了事”,成为AI产品经理必须掌握的核心能力。与传统大模型评测关注回答质量不同,Agent评测需要综合评估任务规划、工具调用、多轮对话一致性以及失败自愈等行为。任务完成率与工具调用成功率是最关键的两个量化指标,同时还需关注延迟与Token成本等工程约束。在实际落地中,评测集的设计要覆盖业务主流程与边界场景,并通过批量回归测试与版本对比,为产品选型、算法迭代和上线决策提供数据支持。本文系统拆解了Agent评测的完整流程,帮助

weixin_29057163的博客 344

如何设计QR反激变换器

摘要:本文分析了基于GaN技术的PD适配器市场现状,重点探讨了准谐振反激变换器(QR Flyback)的工作原理及设计方法。文章首先介绍了反激变换器的三种工作模式(CCM、DCM、CRM/QR)及其特点,指出QR模式通过谷底开通技术能显著降低开关损耗。随后以65W适配器为例,详细阐述了变压器参数设计流程,包括匝比确定、原边电感计算和绕组匝数设计等关键步骤。文章强调QR反激变换器凭借高效率、小体积和低成本优势,已成为20W-65W PD适配器的主流拓扑方案,配合GaN技术进一步提升了功率密度和便携性。

m0_62868254的博客 1496

C++17详解

C++11 是 C++ 语言的一次重大更新。它带来了许多现代特性,如 lambda 表达式、常量表达式(constexpr)、可变参数模板、多线程、基于范围的for循环、智能指针等强大元素,标志着该语言取得了巨大进步。之后的 C++14 是一次较小的更新,它改进了先前标准中的一些内容,并增加了一些小特性。虽然C++17不像C++11那样变化巨大,但它比 C++14 的改动更大,带来了许多令人激动的新增内容和改进。本书将带你逐一了解这些变化!

左雪菲的专栏 1237

内网渗透—横向移动&IPC横移&Impacket套件&CS插件

以上便是IPC横移的知识。最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

2301_76227305的博客 1890

C++17 std::any 深度解析:类型安全万能容器的实现原理与嵌入式实践

类型擦除是一种在接口层面隐藏具体类型信息,将其作为通用实体处理的技术,其核心原理是通过虚函数表或函数指针实现运行时多态,从而在编译后仍能安全地操作不同类型的数据。这项技术的核心价值在于提供了处理异构数据的统一接口,极大地增强了代码的灵活性和可扩展性。它在配置管理、消息传递、插件系统和脚本语言绑定等需要动态处理多种数据类型的场景中发挥着关键作用。本文聚焦于 C++17 引入的 std::any,它正是类型擦除思想的一个标准化实现,旨在提供一个类型安全的通用值容器。我们将深入剖析其内部机制,特别是小对象优化对性

weixin_34296641的博客 381

【UE5】RTS游戏的框选功能+行军线效果实现

步骤: 一、项目准备; 二、框选NPC并移动到指定地点; 三、框选效果; 四、行军线效果

ChaoChao66666的博客 2378

AgentScope Java 2.0 项目实战:使用AgentScope Builder 构建企业级多租户 AI Agent 平台

本文基于 AgentScope Builder 源码深度分析,系统讲解多租户 AI Agent 构建平台的完整开发流程。涵盖 Spring Boot 3.x + WebFlux 后端架构、React 18 + TypeScript 前端实现、HarnessAgent 运行时、CompositeFilesystem 多租户隔离、SSE 流式对话、6 种 IM 渠道接入(钉钉/飞书/企微/GitHub/GitLab)、Git 与 Nacos 技能市场、JWT 认证、Docker Sandbox 隔离等核心技术。

program哲学 723

C++17新特性详解与工程迁移实践指南

现代C++的演进并非一蹴而就,而是通过一次次标准迭代逐步完善。C++17作为连接C++11/14与C++20的关键版本,在语言特性和标准库层面都带来了大量实用改进。理解这些改进的原理,有助于开发者更高效地编写类型安全、零开销抽象的代码。结构化绑定简化了多返回值处理,if constexpr让模板分支逻辑更清晰,std::string_view实现零拷贝字符串操作,std::filesystem则统一了跨平台路径处理。这些特性不仅提升了代码可读性,也为性能优化提供了新思路。当项目需要从C++14迁移到C++1

weixin_33910460的博客 320

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++ 标准库组件详解

C++ 标准库组件详解

happy3581的博客 164

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C++17 optional的使用(注意使用any,optional,function,variant)

一:可以返回空值,就是有数据和没有数据都可以返回,而不需要再加一个bool去判断

qq_38409301的博客 998

C++数据类型深度解析:从基础类型到现代工具,提升代码质量与性能

数据类型是编程语言中用于定义数据存储格式和操作方式的基础概念,它决定了数据的取值范围、内存占用和可执行的操作。在C++中,类型系统从内置基础类型(如整型、浮点型)延伸到用户自定义类型(如结构体、类),并通过类型修饰符(如const、volatile)赋予更多语义。理解类型原理对于编写高效、安全的代码至关重要,它能有效防止内存泄漏、数据溢出等常见问题,并直接影响程序性能。在实际工程中,类型选择需结合具体应用场景,例如金融计算需避免浮点误差,嵌入式系统需考虑内存占用,而高性能计算则需关注数据对齐与缓存友好性。本

weixin_34199405的博客 496

面试之C++17

结构化绑定 可以绑定pair,tuple,数组,结构体,结构化绑定以后也可以修改原值,也可以使自定义类型支持结构化绑定,但是要修改std,感觉没什么必要。 std::tuple<int, double> func_two() { return std::tuple(1, 2.2); } auto[i, d] = func_two(); cout << i << " " << d << endl; map<int, string&g

xupeng1644的博客 1067
上一篇: C++ STL之互斥锁与条件变量详解
下一篇: C++ STL 之随机数生成详解
Ricky_Theseus
博客等级 码龄3年 126粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ricky_Theseus

感谢大家,祝您生活愉快

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值