c++constexpr

constexpr

什么是constexpr?

constexpr 表示"这个值(或函数)可以在编译期计算出来"。它不是"常量",而是" 编译时可确定的表达式"。

constexpr引入的原因

在 C++ 中,有些地方必须用编译期常量,比如:

  • 数组大小:int arr[N];N 必须是编译期已知
  • 模板参数:std::array<int, N>N 必须是常量表达式
  • switch 的 case 值等

早期只能用 #defineenum,但它们不安全、没类型。

于是 C++11 引入了 constexpr ------ 让普通函数和变量也能参与编译期计算

constexpr 的演进(各版本增强)

C++ 版本 constexpr 能力
C++11 只能用于简单变量和极简函数(不能有循环、分支、局部变量等)
C++14 放宽限制:允许循环、条件、局部变量、多个 return 等(接近普通函数)
C++17 新增 if constexpr(编译期 if),彻底改变模板编程
C++20 几乎所有函数都能 constexpr(包括虚函数、动态内存 new/delete、异常等)

constexpr vs const ------ 关键区别

特性 const constexpr
含义 "运行时常量"(一旦初始化就不能改) "编译时常量"(必须在编译期算出)
初始化时机 运行时(如函数内) 编译时
能否用于数组大小? 一般不行 可以
编译时优化 可能优化 肯定优化(值直接替换)

const :承诺运行时 不会变
constexpr :承诺编译时就能算出来

关键点 :所有constexpr都是const,但不是所有const都是constexprconstexpr是更严格的const,加了"必须在编译时确定"的要求。

C++17 的革命性特性 --if constexpr

c++17之前,模板代码必须为所有类型都能编译

cpp 复制代码
template<typename T>
void print(T value) {
    // 下面的代码必须对所有T类型都有效
    if (std::is_pointer<T>::value) {
        std::cout << *value;  // 如果T不是指针,这行编译错误!
    } else {
        std::cout << value;
    }
}

即使程序逻辑上不会执行*value,编译器也必须检查语法正确性!

c++17 if constexpr编译时决定哪些代码被编译

cpp 复制代码
template<typename T>
void print(T value) {
    if constexpr (std::is_pointer_v<T>) {
        // 只有T是指针时,这整块代码才会被编译
        std::cout << *value;  // 安全!编译器知道T一定是指针
    } else {
        // 只有T不是指针时,这整块代码才会被编译
        std::cout << value;
    }
}

与传统if的区别

特性 普通 if if constexpr
检查时机 运行时 编译时
所有分支都要编译吗? 都要语法检查 只编译符合条件的
能用于不同类型返回吗? 不可以 可以
能用于函数签名吗? 不可以 可以
相关推荐
咩咦12 分钟前
C++学习笔记22:前置后置 ++/-- 和日期减日期
c++·学习笔记·运算符重载·日期类·前置++·后置++·日期减日期
计算机安禾17 分钟前
【c++面向对象编程】第40篇:单例模式(Singleton)的多种C++实现
开发语言·c++·单例模式
_日拱一卒32 分钟前
LeetCode:114二叉树展开为链表
java·开发语言·算法
天天进步201534 分钟前
从零打造 Python 全栈项目:智能教学辅助系统
开发语言·人工智能·python
一个不知名程序员www44 分钟前
算法学习入门---算法题DAY1
c++·算法
kkeeper~1 小时前
0基础C语言积跬步之内存函数
c语言·开发语言
吃好睡好便好1 小时前
在Matlab中绘制杆状图
开发语言·学习·算法·matlab·信息可视化
桀人1 小时前
C++——内存管理——new和delete的超详细解析
开发语言·c++
Shadow(⊙o⊙)1 小时前
Shell进程替换,自定义Shell解释器——字符串库函数灵活操作!
linux·运维·服务器·开发语言·c++·学习
_F_y1 小时前
树形 DP 从入门到进阶:普通树形DP、树形背包、换根DP
c++·动态规划