0

0

C++中的constexpr是什么?(如何实现编译期计算)

穿越時空

穿越時空

发布时间:2026-02-21 14:10:03

|

564人浏览过

|

来源于php中文网

原创

constexpr函数需满足:函数体符合标准要求(c++11仅单return,c++14+支持分支循环等)、参数为字面量类型且传入常量表达式、调用处于常量表达式上下文(如数组长度、模板参数),三者缺一不可。

c++中的constexpr是什么?(如何实现编译期计算)

constexpr 函数必须满足哪些条件才能真正编译期求值

不是标了 constexpr 就能在编译期运行——它只是“允许”编译器在常量表达式上下文中求值。真正在编译期执行,得同时满足:函数体足够简单(C++11 仅支持单个 return 表达式;C++14 起支持局部变量、循环、分支等)、所有参数都是字面量类型且传入的是常量表达式、调用发生在需要常量表达式的语境里(比如数组长度、模板非类型参数)。

常见错误现象:constexpr int f(int x) { return x * 2; } 定义合法,但 f(5) 在运行时调用就只是普通函数调用;只有像 int arr[f(5)];static_assert(f(5) == 10); 这类地方,才强制触发编译期计算。

  • 参数必须是字面量类型(intstd::string_view(C++20)、自定义 constexpr 构造的类等),不能是 std::string 或带虚函数的类
  • C++17 起支持 constexpr lambda,但捕获变量必须是常量表达式
  • 函数内不能有未定义行为(如除零、越界访问),否则即使没被调用也会导致编译失败

constexpr 变量和 const 变量到底差在哪

const 只保证运行时不修改,值可能来自运行时(比如 const int x = rand(););而 constexpr 变量必须在编译期就能确定值,且隐含 const 属性。

使用场景差异明显:模板参数要求字面量,只能用 constexpr 变量;switch 的 case 标签也只接受常量表达式,const int x = 42; 不够,得写成 constexpr int x = 42;

立即学习C++免费学习笔记(深入)”;

Summarizer
Summarizer

基于 AI 的文本段落摘要生成器

下载
  • constexpr 变量定义时就必须初始化,且初始化器必须是常量表达式
  • 指针可以是 constexpr,但所指对象不一定是编译期可知的(比如 constexpr int* p = &global_var; 合法,只要 global_var 是静态存储期且已定义)
  • 对类成员用 constexpr,需确保构造函数和成员都满足字面量要求;C++20 起支持 constexpr new,但堆内存仍无法在编译期“存在”

为什么 constexpr if 能解决 SFINAE 的可读性问题

constexpr if(C++17)本质是编译期分支裁剪:条件为假的分支会被完全丢弃,不参与语法检查或实例化。这比传统 enable_if 模板重载更直接——后者靠编译器“试错”来排除非法重载,错误信息往往晦涩难懂。

常见错误现象:在 constexpr if 分支里写了非法代码(比如对非指针类型调用 ->size()),如果该分支未被选中,编译通过;一旦条件变真,立刻报错,定位清晰。

  • 条件必须是常量表达式,不能是运行时变量(哪怕变量本身是 constexpr
  • 分支内声明的变量作用域仅限该分支,不会泄露到外层
  • 不能用在函数参数默认值、基类列表等非语句上下文中

constexpr 构造函数容易忽略的限制点

类要成为字面量类型(literal type),才能用于 constexpr 上下文,而 constexpr 构造函数只是必要条件之一。很多开发者以为加了 constexpr 就万事大吉,结果发现对象还是不能当模板参数用。

关键在于:类的所有非静态成员必须是字面量类型;析构函数不能是用户定义的(C++20 前);没有虚函数、虚基类;且构造函数体必须满足 constexpr 函数的所有约束(比如 C++11 中不能有 try/catch)。

  • 聚合类(aggregate)天然支持 constexpr 初始化,不需要显式构造函数(如 struct Point { int x, y; }; constexpr Point p{1, 2};
  • C++20 允许 constexpr 析构函数,但若析构函数中有运行时副作用(如 std::cout),则整个对象无法用于常量表达式
  • 继承体系中,基类也必须是字面量类型,否则派生类的 constexpr 构造函数无效

最常被绕过的点:constexpr 不等于“编译期存在”,它只保证“可计算”,不代表对象内存布局或地址在编译期固定(除非用 consteval 强制)。别指望用 constexpr 挤掉所有运行时开销——它只是给你一把钥匙,开哪扇门还得看标准和编译器是否真把那扇门造出来了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

810

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1555

2023.10.24

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

826

2023.08.22

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

559

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

435

2024.03.13

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

549

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

810

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

578

2024.08.29

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

796

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.8万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 18.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号