C++编译时计算革命:constexpr函数如何让程序快如闪电(仅限高手掌握)

第一章:C++编译时计算革命:constexpr函数如何让程序快如闪电(仅限高手掌握)

在现代C++开发中,constexpr 函数是实现编译时计算的核心工具。它允许开发者将复杂的逻辑移至编译阶段执行,从而在运行时完全消除计算开销,极大提升性能。

什么是constexpr函数

constexpr 函数是一种可在编译期求值的函数,只要其参数为常量表达式,编译器就会在编译时计算结果。否则,它仍可在运行时正常调用。
// 编译时计算阶乘
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

// 在编译时计算并初始化数组大小
constexpr int fact_5 = factorial(5); // 结果为120,编译时完成
该函数在传入字面量或常量时,由编译器直接展开计算,生成常量值,避免了运行时递归调用。

constexpr的优势与限制

  • 显著减少运行时开销,适用于数学计算、查找表生成等场景
  • 支持递归和条件判断,但必须保证所有路径在编译时可求值
  • 不能包含动态内存分配、异常抛出或非constexpr函数调用

实际应用场景对比

场景传统方式constexpr优化后
数组长度计算宏定义或运行时计算编译时确定,类型安全
字符串哈希运行时循环计算编译期生成哈希值
利用constexpr,开发者能写出既高效又安全的代码,真正实现“零成本抽象”。掌握这一特性,是迈向高性能C++编程的关键一步。

第二章:深入理解constexpr函数的核心机制

2.1 constexpr函数的语法规范与编译期约束

`constexpr` 函数是 C++11 引入的重要特性,允许在编译期求值。其定义需满足特定语法规范:函数体必须仅包含一条可计算的表达式(C++14 起放宽限制),且所有参数和返回类型必须为字面类型。
基本语法结构
constexpr int square(int n) {
    return n * n;
}
该函数在传入编译期常量时,如 constexpr int val = square(5);,将在编译期完成计算。若参数为运行时变量,则退化为普通函数调用。
编译期约束条件
  • 函数体内不能包含未定义行为或无法在编译期执行的操作(如动态内存分配)
  • 局部静态变量在 C++14 前不被允许
  • 递归调用深度受限于编译器实现
特性C++11 支持C++14 改进
多条语句否是
循环支持有限(递归模拟)直接支持 for/while

2.2 编译时求值的条件与常量表达式上下文

在 Go 语言中,编译时求值依赖于**常量表达式上下文**。只有在该上下文中,表达式才能被认定为编译期可计算。
常量表达式的合法操作
支持的操作包括算术运算、位运算、比较运算等基础操作,且所有操作数必须是常量。
const (
    a = 3 + 5        // 合法:编译时求值
    b = a >< 2       // 合法:位移操作
    c = "hello" + "world" // 字符串拼接
)
上述代码中,所有值均在编译阶段确定。a 的值为 8,b 为 32,c 为 "helloworld"。
非常量上下文限制
局部变量或函数调用返回值无法参与常量表达式:
  • 函数返回值不能用于 const 定义
  • 运行时计算的值不满足编译时求值条件

2.3 constexpr与const、inline的区别与联系

基本概念辨析
const用于声明不可变对象,其值可在运行时确定;constexpr则要求在编译期求值,适用于常量表达式;而inline用于解决函数多重定义问题,并提示编译器尝试内联展开。
语义与使用场景对比
  • const:运行时常量,如 const int size = getValue();
  • constexpr:必须在编译期计算,如 constexpr int square(int x) { return x * x; }
  • inline:主要用于函数,避免链接冲突,提升性能
constexpr int fib(int n) {
    return (n <= 1) ? n : fib(n - 1) + fib(n - 2);
}
constexpr int val = fib(5); // 编译期计算,val = 5
该函数在编译时完成递归计算,体现了constexpr的编译期求值能力,而const无法保证此行为。
三者协同应用
特性constconstexprinline
求值时机运行时编译期N/A
适用对象变量变量/函数函数
内存优化否是是(减少调用开销)

2.4 函数调用在常量表达式中的合法性分析

在现代编程语言中,常量表达式的求值必须在编译期完成。因此,并非所有函数调用都能合法出现在常量上下文中。
constexpr 函数的约束条件
只有被标记为 constexpr 且满足特定条件的函数才能在常量表达式中调用。这些条件包括:函数体不能包含异常抛出、动态内存分配或未定义行为。

constexpr int square(int x) {
    return x * x;
}

constexpr int val = square(5); // 合法:编译期可计算
该函数在编译期完成计算,val 被赋予常量值 25,符合常量表达式要求。
非法调用示例与限制
  • 普通函数无法在 constexpr 上下文中调用
  • 包含运行时语义(如 I/O)的操作被禁止
  • 递归深度超过编译器限制将导致编译失败

2.5 编译器对constexpr函数的优化路径剖析

编译器在处理 `constexpr` 函数时,会依据调用上下文决定是否在编译期求值。若所有参数在编译期已知,函数将被移至常量折叠阶段执行。
编译期求值判定条件
  • 函数必须被声明为 constexpr
  • 调用时所有实参均为常量表达式
  • 函数体满足编译期可执行限制(如无动态内存分配)
优化前后对比示例
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}
// 使用
constexpr int val = factorial(5); // 编译期计算为 120
上述代码中,factorial(5) 在编译期展开并代入结果,避免运行时代价。递归调用被静态解析,最终生成常量值。
优化流程示意
源码 → 语法分析 → 常量传播 → 表达式折叠 → 目标代码

第三章:constexpr函数的实战编程技巧

3.1 实现编译时数学运算库:阶乘与斐波那契数列

在现代C++中,利用模板元编程可以实现编译时计算,显著提升运行时性能。通过 constexpr 和模板递归,可在编译阶段完成数学运算。
编译时阶乘实现

template
struct Factorial {
    static constexpr int value = N * Factorial::value;
};

template<>
struct Factorial<0> {
    static constexpr int value = 1;
};
该模板通过递归特化实现阶乘计算。当 N 为 0 时终止递归,返回 1;否则递归计算 N × (N-1)!,所有结果在编译期确定。
斐波那契数列的编译时构造
  • 使用模板递归定义 Fibonacci<N> = Fibonacci<N-1> + Fibonacci<N-2>
  • 基础情形:Fibonacci<0> = 0,Fibonacci<1> = 1
  • 结果嵌入二进制,无运行时开销

3.2 构建类型安全的编译时字符串哈希

在现代C++开发中,运行时字符串比较常成为性能瓶颈。通过 constexpr 与模板元编程,可将字符串哈希计算移至编译期,提升执行效率。
编译期FNV-1a哈希实现
constexpr uint32_t constHash(const char* str, size_t len) {
    uint32_t hash = 0x811c9dc5;
    for (size_t i = 0; i < len; ++i) {
        hash ^= str[i];
        hash *= 0x01000193;
    }
    return hash;
}
该函数在编译时计算字符串哈希值,使用FNV-1a算法保证低冲突率。参数 str 指向字符串首地址,len 为长度,由调用者确保有效性。
类型安全封装
利用模板字面量运算符,可构建类型安全的哈希字面量:
  • 避免运行时重复计算
  • 防止非法字符串输入
  • 支持 switch 语句直接匹配

3.3 利用constexpr提升模板元编程可读性

在C++11引入constexpr后,编译期计算的能力被显著增强。相比传统模板元编程中复杂的递归特化与类型推导,constexpr允许开发者以更直观的函数式风格编写可在编译期求值的逻辑。
从模板递归到constexpr函数
传统模板元编程实现阶乘需依赖递归特化:
template<int N>
struct Factorial {
    static constexpr int value = N * Factorial<N - 1>::value;
};

template<>
struct Factorial<0> {
    static constexpr int value = 1;
};
该方式语法冗长且调试困难。使用constexpr可简化为普通函数形式:
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}
此版本语义清晰,支持变量、循环和条件判断,极大提升了可读性与维护性。
编译期验证示例
调用factorial(5)在编译期即可展开为常量120,可用于数组大小定义或模板参数传递,兼具性能与表达力。

第四章:高级应用场景与性能极致优化

4.1 编译时查找表生成与静态数据结构构建

在现代高性能系统中,将计算密集型的查找表构建移至编译阶段可显著提升运行时效率。通过常量表达式(`consteval`)和模板元编程,可在编译期完成复杂数据结构的初始化。
编译期查表优化示例

consteval std::array<int, 256> generate_sine_table() {
    std::array<int, 256> table{};
    for (int i = 0; i < 256; ++i) {
        table[i] = static_cast<int>(std::sin(i * 3.14159 / 128) * 1000);
    }
    return table;
}
constexpr auto SINE_TABLE = generate_sine_table();
上述代码利用 `consteval` 确保函数仅在编译期求值,生成一个预计算的正弦值查找表。`SINE_TABLE` 被内置于可执行文件的数据段,避免运行时重复计算。
优势与应用场景
  • 减少运行时CPU负载,尤其适用于嵌入式系统
  • 提高确定性响应时间,满足实时系统需求
  • 结合 constexpr 容器实现零成本抽象

4.2 结合模板参数推导实现零成本抽象

在现代C++中,模板参数推导为实现零成本抽象提供了核心支持。通过`auto`和泛型lambda,编译器能在不牺牲性能的前提下自动推导类型,消除冗余运行时开销。
模板推导与性能优化
利用函数模板的隐式实例化,可编写高度通用且无额外成本的代码:
template
void process(const Container& c) {
    for (const auto& item : c) {
        // 编译期确定容器类型,生成最优指令
    }
}
上述代码中,`Container`类型在调用时被自动推导,生成针对具体类型的专用版本,避免虚函数调用或指针间接寻址。
优势对比
  • 编译期类型绑定,无运行时开销
  • 支持内联优化,提升执行效率
  • 接口简洁,降低使用复杂度

4.3 在策略模式中嵌入constexpr逻辑分支

在现代C++设计中,策略模式可通过constexpr实现编译期行为选择,提升运行时性能。
编译期策略选择机制
通过if constexpr,可在模板实例化时决定执行路径:
template<typename Strategy>
void execute(int val) {
    if constexpr (std::is_same_v<Strategy, FastPath>) {
        // 编译期确定,无运行时开销
        optimize(val);
    } else {
        fallback(val);
    }
}
该代码在模板展开时根据Strategy类型剔除无效分支,生成最优机器码。
性能对比
策略类型分支判断时机运行时开销
传统虚函数运行时高(间接调用)
constexpr条件编译期无

4.4 避免常见陷阱:动态内存与异常的规避策略

在C++等支持手动内存管理的语言中,动态内存分配常伴随资源泄漏与悬空指针等风险。结合异常处理机制时,若未妥善管理资源生命周期,极易引发不可预测行为。
RAII:资源获取即初始化
利用对象构造与析构的确定性,自动管理资源。智能指针如std::unique_ptr可有效规避内存泄漏。

std::unique_ptr<int> ptr(new int(42));
// 异常抛出时,ptr自动释放内存
throw std::runtime_error("error");
上述代码中,即使发生异常,智能指针析构函数仍会被调用,确保内存释放。
异常安全的三大保证
  • 基本保证:操作失败后,对象仍处于有效状态
  • 强保证:操作要么完全成功,要么回滚到原始状态
  • 不抛异常保证:操作必定成功且不抛出异常
合理设计接口并使用noexcept说明符,有助于提升系统稳定性与性能。

第五章:未来展望:constexpr在C++26及以后的演进方向

随着C++标准的持续演进,constexpr机制正朝着更强大、更灵活的方向发展。C++26计划引入多项关键改进,旨在消除当前编译时计算的限制,提升元编程能力。
更广泛的动态内存支持
未来的constexpr函数有望允许在编译期使用new和delete操作。这意味着可以在编译时构造复杂的数据结构,如constexpr std::vector。
constexpr auto build_lookup_table() {
    std::vector<int> table;
    for (int i = 0; i < 100; ++i) {
        table.push_back(i * i + 2 * i + 1);
    }
    return table; // C++26 可能允许
}
反射与constexpr结合
通过将静态反射提案与constexpr融合,开发者可在编译期遍历类成员并生成序列化代码:
  • 自动推导结构体字段名称
  • 生成JSON序列化/反序列化逻辑
  • 减少运行时类型信息依赖
异常支持的扩展
当前constexpr函数不允许抛出异常。C++26可能允许在编译期抛出异常,便于在模板实例化时提供更清晰的错误反馈:
特性C++23C++26(预期)
堆内存分配不支持支持
异常抛出禁止允许
虚函数调用受限增强支持
编译期I/O的可能性
尽管存在争议,部分提案探索允许读取编译时可用的文件内容,用于生成资源嵌入代码:
源码 → 预处理器读取二进制文件 → constexpr数组初始化 → 内联至可执行文件
编译时魔法:constexpr 的超能力与性能飞跃 在现代 C++ 中,constexpr 是一种非常强大的编译时计算工具,它不仅能优化程序的执行效率,还能减少运行时的计算负担。这一特性对于编写高效、响应迅速的应用程序尤其重要。在本文中,我们将深入探讨 constexpr 在不同应用场景中的性能表现,通过实验对比来展示其带来的优势。让我们一起看看这个被编译器“施加魔法”的特性如何在实际中大放异彩。 阅读详情

相关推荐

C++中constexpr函数

1 简介 constexpr函数指的是在编译的时候就能得到其返回值的函数,也就是说编译器将constexpr函数直接转换成其返回值,因此,constexpr函数都是被隐式地定义为内联函数。使用constexpr关键字来修饰constexpr函数。 2 使用方法 有如下代码: constexprintmyFunc() { return1; } constexprinti = myFunc() * 4; 此时,编译器会将myFunc()函数用其返回值1来代替,在编译时就可知i的值是4。...

hou09tian的博客 1万+

c++nullptr(空指针常量)、constexpr(常量表达式)

总述 又来更新了,今天带来的是nullptr空指针常量、constexpr(常量表达式)C++的两个用法。Result result_fun =nullptr;constexprstatic uint32_t try_times = 100;这是两个在工作中常用的C++操作,但是你知道nullptr和constexpr由来以及它们的更多用法吗? 下面听我一一道来。 作者:良知犹存 转载授权以及围观:欢迎添加微信公众号:羽林君 一、nullptr ...

良知犹存的博客 1034

C++编程法则365天一天一条(28)constexpr编译时期计算

它修饰的表达式本身在编译期间可知, 并且编译器会尽可能的 evaluate at compile time. 在constexpr 出现之前, 可以在编译期初始化的const都是implicit constexpr. 直到c++ 11, constexpr才从const中细分出来成为一个关键字, 而 const从1983年 c++ 刚改名的时候就存在了…如果你将一个变量标记为constexpr,则同样它是const的。但相反并不成立,一个const的变量或函数,并不是constexpr的。

二进制君 3128

C++常见知识点疑惑整理

C++基础

lily_i的博客 396

基于STM32与OV7670的嵌入式视频监控系统设计与实现

本文详细介绍了基于STM32单片机与OV7670摄像头的嵌入式视频监控系统设计与实现。从硬件选型、电路设计到软件开发,涵盖了摄像头驱动、TFT显示优化及图像处理等关键技术,提供了实用的调试技巧和性能优化方案,为低成本、高效率的视频监控系统开发提供完整解决方案。

desk3的博客 802

Linux中断子系统(二)—— 通用框架处理

1、数据结构分析 (1)中断描述符结构structirq_desc: 1)打开CONFIG_SPARSE_IRQ宏(中断编号不连续),中断描述符以radix- tree来组织,用户在初始化时进行动态分配,然后再插入radix-tree中; 2)关闭CONFIG_SPARSE_IRQ宏(中断编号连续),中断描述符以数组的 形式组织,并且已经分配好; 3)不管哪种形式,最终都可以通过linuxirq号来找到对应的中断描述符; (2)stru...

weixin_38428439的博客 4871

《C++11标准库》3.1.8关键字constexpr与const

自 C++11起,constexpr 可用来让表达式核定于编译期。例如: constexpr int square (int x) { return x*x; } float a[square(9)];//此数组大小为81 这个关键字修正了在C++98中使用数值极限时出现的问题,在C++11之前,如下代码: std::numeric_limits<short>::max() 无法被用作一个常量,虽然他在功能上等同于宏 INT_MAX。如今,在C++11中,这样的一个式子被声

weixin_60351940的博客 487

LSTM 怎么进行二维数据的输入呢

尽管LSTM并不天然地适用于处理图像、视频等二维数据,但通过时间序列化、卷积特征提取和双向LSTM等方法,我们可以将二维数据转化为适合LSTM输入的形式,从而利用LSTM的强大记忆能力和长期依赖学习能力对二维数据进行建模。未来的研究方向可以考虑将LSTM与其他模型结合,例如将LSTM与卷积神经网络(Convolutional Neural Network, CNN)结合,利用CNN提取图像的空间特征,然后利用LSTM学习时间序列的长期依赖;

xiamu_CDA的博客 1038

constexpr

constexptr和常量表达式 常量表达式是指值不会改变并且在编译过程中就能得到计算结果的表达式。 编译过程中得到计算结果。 字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。 一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定。 (注意!!!)对于这条语句:const int sz = get_size();,sz本身是常量,但它的具体值...

傻月菇凉的博客 1万+

WebVTT中的文本轨道(Text Tracks,TT)到底是什么鬼?

WebVTT,全称是The Web Video Text Tracks Format,意思是网络视频文本轨道格式。那么到底什么是文本轨道(Text Tracks)呢?这篇文章希望一探究竟。

码农1479的博客 1986

华为EC6108V9E刷机实战:从U盘准备到开机优化的完整避坑指南

本文提供华为悦盒EC6108V9E刷机与优化的完整实战指南。针对搭载RK3228芯片和安卓4.4.4系统的设备,从型号确认、固件选择、U盘准备,到详细刷机步骤、常见故障排除,以及刷机后的深度性能优化,手把手帮助用户规避风险,让旧盒子焕发新生,成为流畅的全能媒体中心。

weixin_29324401的博客 1193

C++ constexpr类型说明符

关键字 constexpr 于 C++11 中引入并于 C++14 中得到改善。它表示常数表达式。与 const 相同,它可应用于变量,因此如果任何代码试图修改该值,均将引发编译器错误。与 const 不同,constexpr 也可应用于函数和类构造函数。 constexpr 指示值或返回值是常数,并且如果可能,将在编译时计算值或返回值。 1 constexpr 变量 const 和 co...

coolwriter的博客 1202

从原理图到代码:深入解析SX1278 LoRa模块与STM32的SPI通信驱动(附完整工程)

本文深入解析了SX1278 LoRa模块与STM32的SPI通信驱动实现,从硬件原理图到完整工程代码,详细介绍了LoRa技术的通信原理、寄存器配置、SPI接口设计及低功耗优化策略。适合物联网开发者和嵌入式工程师提升远距离无线通信能力,附完整工程代码助力快速开发。

weixin_42715608的博客 424

C++之constexpr 编译时计算

constexpr是C++从11标准开始引入的核心特性,它代表“常量表达式”,旨在将计算从运行时转移到编译时,实现真正的零开销抽象。其核心思想是:允许编译器在编译期间执行函数和对象初始化,从而消除运行时开销,同时增强代码安全性。演进历程展现了C++对编译时计算能力的持续强化。C++11中,constexpr函数只能包含单条return语句,主要用于基础数学计算。C++14解除了函数体限制,允许循环、分支和局部变量,使复杂算法得以编译时执行。

m0_45074715的博客 727

Matlab 轴承信号仿真+分析

文章目录项目说明1、信号仿真1.1 仿真公式1.2 信号参数设置1.3 代码实现2、仿真信号分析2.1 小波变换2.2 快速谱峭度 项目说明 本文主要解决两个问题: 1、仿真包含周期性冲击信号、随机干扰冲击信号、调制干扰信号以及随机噪声四个成分的故障轴承信号; 2、使用小波变换以及快速谱峭度对该仿真信号进行分析。 1、信号仿真 1.1 仿真公式 这里的仿真信号公式主要参考了包文杰学者的硕士论文《加权谱峭度故障诊断方法研究与应用》,列举公式如下: 周期性冲击信号仿真 随机干扰冲击信号仿真 调制

cocofisher的博客 9267

20 硬件工程师笔面试高频考点真题解析——寄存器

摘要: 寄存器是由多个边沿触发的D触发器组成的多位存储单元,用于同步时序电路中的数据暂存、隔离毛刺、跨时钟域同步等。选型需考虑位宽、触发方式(边沿/电平)、异步控制、电气参数等。核心时序参数包括建立时间(Tsu)、保持时间(Thold)和时钟输出延迟(Tco)。寄存器广泛应用于时序逻辑、流水线分割、毛刺消除、跨时钟域同步及计数分频等场景。同步复位依赖时钟边沿,时序易收敛但需时钟支持;异步复位独立于时钟,上电可靠但需注意亚稳态风险。

XU157303764的博客 1342

C++编译时计算革命(constexpr扩展全解析)

掌握编译时计算新范式,提升性能与安全。2025全球C++及系统软件技术大会:constexpr扩展赋能编译时计算的技术突破,深入解析C++23/26中constexpr在元编程、模板优化与系统级应用的实战方法,实现零成本抽象与高效编译优化,值得收藏。

DevPath的博客 977

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

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

C++ constexpr 修饰符与函数

本文介绍了C++中constexpr修饰符的核心概念与应用。constexpr用于指定对象或函数可以在编译期计算,带来性能优化和代码安全性提升。

平平无奇的小甜菜 1567

深度学习工具包 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")

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++ constexpr:编译时计算的高效秘籍

本文探讨了C++中constexpr关键字的用法,它支持编译时计算以提高程序性能。constexpr适用于变量和函数,要求值在编译时确定。文章展示了正确使用constexpr函数的示例,计算两数之和并在编译时完成。同时指出constexpr的类型限制,包括基本数据类型和满足条件的用户定义类型。还列举了常见编译时错误,如修改constexpr变量、使用非constexpr函数等。正确使用constexpr能提升代码效率,但需遵循其严格规则。

大四在找工作,如果公司有需要的可以联系我13086825462@163.com 693

【C++26前瞻】:constexpr函数支持IO?编译时计算边界再突破

突破编译时计算极限,解锁constexpr新能力。2025全球C++及系统软件技术大会揭示constexpr扩展如何支持IO操作,推动C++26在编译期实现更复杂逻辑,提升性能与安全性,值得收藏。

GatherLume的博客 758

如何利用C++20 constexpr虚函数实现编译时多态:完整指南

现代C++特性库(modern-cpp-features)是C++开发者的必备参考资料,其中C++20引入的constexpr虚函数功能彻底改变了编译时多态的实现方式。本文将详细介绍这一革命性特性的使用方法、实际应用场景和最佳实践,帮助开发者充分利用编译时计算提升程序性能。 ## constexpr虚函数:打破编译时多态限制 在C++20之前,虚函数无法在constexpr上下文中使用,这极大

gitblog_00046的博客 802

[C++11] constexpr 完整解析

constexpr是C++11标准引入的一个关键字,旨在支持编译时常量表达式的计算。constexpr的主要目的是提高程序性能,通过在编译时计算常量值来减少运行时的计算负担。这个特性使得程序员能够编写更加高效和可读的代码,并且能够利用编译器进行更多的优化。

wangdsh的博客 3589

C++11/C++14中constexpr的使用

C++11/C++14中constexpr的使用

网络资源是无限的 7178

编译时元对象生成:Verdigris constexpr黑科技原理解析

Verdigris是一个革命性的开源项目,它通过constexpr黑科技实现了编译时元对象生成,让开发者能够摆脱Qt框架中moc(元对象编译器)的束缚。这一创新技术不仅简化了开发流程,还带来了性能优化和代码可维护性的提升。 ## 🚀 什么是元对象系统?为何需要编译时生成? Qt框架的核心在于其元对象系统(Meta-Object System),它为Qt提供了信号槽、属性系统、动态类型信息等关

gitblog_00065的博客 1051

揭秘C++26 constexpr新特性:如何实现100%编译时计算优化

掌握C++26 constexpr编译时计算新特性,实现代码性能质的飞跃。详解如何在模板元编程与常量表达式中达成100%编译期求值,提升运行效率并减少资源开销。适用于高性能计算与嵌入式场景,优化编译速度与可维护性,值得收藏。

LogicGap的博客 621

C++23 对部分特性的 constexpr 支持

是一个固定大小的位序列容器,在 C++23 之前,仅有一个构造函数和operator[]被标记为constexpr。P2417R2 提案对的constexpr接口进行了扩展,鉴于能够是constexpr的所有内部结构以及完整的 API 如今都能够是constexpr。是一种智能指针,用于管理动态分配的对象,保证对象的所有权唯一。P2273R3 提案被接纳后,在 C++23 中支持constexpr。用于在运行时获取类型信息,而用于比较两个类型信息对象是否指代相同的类型。在 C++23 之前,typeid。

m0_74823364的博客 939
上一篇: 【C++高手进阶必修课】:用RAII实现零手动释放的资源管控
下一篇: C++模板参数包高效编程指南,提升代码复用率300%
PixelStream
博客等级 码龄1年 177粉丝 2182原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值