
各位老师好!
这是CPP面试冲刺周刊 (c++ weekly) 陪你一起快速冲击大厂面试 第7期
周刊目标:
•
不是成为C++专家,而是成为C++面试专家
本期内容:
•
constexpr、内联函数、编译期元编程
常见误区(反常识):
•
const 修饰变量 分配内存空间吗?什么时候分配,什么时候不分配
#define、const、inline 的局限•
#define 宏常量:不参与类型检查,调试困难。
•
const 变量:虽然安全,但在 C++11 之前,const不保证编译期常量。
•
inline 函数:通过内联展开减少函数调用开销,但依然在 运行期计算。
我们会遇到这种场景:
const int NODE_NUM = 3; //在 C++98 中只是一个 运行期常量,不是 编译期常量。
char buf[NODE_NUM]; // 编译直接报错
因为 NODE_NUM 不是编译期常量,buf 的大小无法在编译期确定,编译错误。
C++11 引入
constexpr,让我们可以在 编译期完成计算,避免运行时开销。
constexpr 的初衷C++11 引入了 constexpr,目标是:
•
让 常量表达式在 编译期完成求值;
•
提高 性能,减少运行期不必要的计算;
•
统一常量语义,避免编译器行为不一致。
改写上面的例子:
constexpr int NODE_NUM = 3; char buf[NODE_NUM]; // ✅ 编译期直接展开
编译器会在 编译期直接把 NODE_NUM 计算成 3,
生成的汇编里,buf 是一个 固定大小的栈数组,根本不会在运行期再算一次。
特性 | inline | const / constexpr | 编译期元编程(模板 + constexpr) |
|---|---|---|---|
目标 | 减少函数调用开销 | 固定值、优化常量表达式 | 利用编译期完成复杂逻辑 |
性能 | 消除调用栈,但仍然运行期求值 | const 多为运行期,constexpr 编译期计算 | 完全避免运行期开销 |
适用场景 | 高频调用的短函数 | 常量定义、查表、状态切换 | 哈希计算、调度策略、数据映射表 |
缺点 | 代码膨胀、编译时间增加 | constexpr 在 C++11 较受限,C++14 才支持更复杂逻辑 | 编译时间长、代码可读性差 |
3fs:代码
static constexpr size_t kNodeIdKeyedMapExpectedNumElements = 1000;
constexpr int kNumIovecs = 64;
std::array<iovec, kNumIovecs> iovecs;
constexpr uint32_t kInvalidatedFlag = 1u << 0u; // Bit 0
constexpr uint32_t kReadAvailableFlag = 1u << 1u; // Bit 1
constexpr uint32_t kReadNewWakedFlag = 1u << 2u; // Bit 2
constexpr uint32_t kWriteAvailableFlag = 1u << 3u; // Bit 3
constexpr uint32_t kWriteNewWakedFlag = 1u << 4u; // Bit 4
constexpr uint32_t kWriteHasMsgFlag = 1u << 5u; // Bit 5
constexpr uint32_t kWriteNewMsgFlag = 1u << 6u; // Bit 6
constexpr uint32_t kLastReadFinished = 1u << 7u; // Bit 7
constexpr uint32_t kLastWriteFinished = 1u << 8u; // Bit 8
在分布式存储和数据库的高性能项目中,constexpr 和编译期元编程适用于 大量重复计算 的场景:
1
哈希值计算 Ceph 的 PG 映射里会用到哈希:
constexpr uint32_t hash(const char* s, size_t n) {
return n ? (hash(s, n-1) * 131 + s[n-1]) : 0;
}
constexpr auto key = hash("pool1", 5);
•
收益:hash 在编译期算完,运行期不消耗 CPU。
2
常量查表 比如 TiDB 的执行计划优化:
constexpr std::array<int, 4> priorities = {1, 2, 4, 8};
•
收益:常量表编译期固化,避免 runtime 初始化。
3
模板 + constexpr 的高性能策略调度
template <typename Strategy>
constexpr auto choose_strategy() {
if constexpr (std::is_same_v<Strategy, SSD>) return "low-latency";
else return "high-throughput";
}
•
收益:调度策略完全在 编译期分发,零运行时分支判断。
constexpr 的本质是 把一部分运行期逻辑前移到编译期,核心是:
1
语法约束
C++11 要求 constexpr 函数必须:
•
单个 return 表达式
•
不允许循环和复杂控制流
•
不允许动态分配内存 → C++14 以后放宽限制,可以写递归、if-else 等复杂逻辑。
2
编译器行为
•
如果输入是编译期常量 → 在编译期计算结果,直接写死到目标代码。
•
如果输入是运行时值 → 退化为普通函数,在运行期执行。
3
示例:编译器直接展开常量
constexpr int square(int x) { return x * x; }
int a = square(3);
编译器会直接把 a 展开为:
mov eax, 9
mov [a], eax
没有函数调用,也没有乘法指令。
在 C++17 和 C++20,constexpr 与 模板元编程 深度结合,让我们能写出接近函数式语言的代码:
template <typename T>
constexpr size_t type_id() {
if constexpr (std::is_same_v<T, int>) return 1;
else if constexpr (std::is_same_v<T, double>) return 2;
else return 0;
}
•
C++17 的 if constexpr 让模板分支只保留必要的代码,消除了未使用分支的编译错误。
•
C++20 的 consteval 更进一步,强制 编译期求值,让性能更加可控。
技术 | 用途 | 收益 | 注意事项 |
|---|---|---|---|
inline | 展开函数,消除调用开销 | 小幅提升性能 | 代码膨胀 |
constexpr | 编译期计算 | 避免运行期重复计算,零开销 | C++11 受限,C++14+ 更强大 |
模板 + constexpr | 编译期分发策略 | 极致性能优化 | 编译时间、可读性 |
实践建议 • 高频小函数:优先
constexpr• 大型查表、哈希:constexpr+std::array• 策略分发:if constexpr+ 模板 • 性能敏感核心逻辑:结合consteval强制编译期求值
曾经有一个让我心跳加速的岗位放在我面前, 我没有珍惜。 等到别人拿到 offer 的那一刻, 我才追悔莫及!
人世间,最痛苦的事情, 不是没钱吃饭, 也不是没房没车, 而是——错过了那个能让我逆天改命的机会!
如果上天再给我一次机会, 我一定会对那个岗位说三个字: “我要你!”
如果非要在这份“心动”上加一个期限, 一万年太久了…… 我只想要——21天!
你可能面临两种选择
“这个岗位太难了,我先准备一下吧。” 于是你准备1天、1周、1个月、1年…… 等再回头,3年就这样过去了。
•
每天忙着搬砖,没时间系统复习
•
每次想起要准备,又感觉心里没底
•
面试知识点更新太快,拿着旧地图找新机会 最后,错过了一次又一次心动的岗位。
终于等来一场面试, 你觉得问题很简单,张口就答, 结果用“几千元思维”回答“百万年薪岗位”。
•
面试官问到C++底层实现,答不上来
•
设计题说到高并发架构,没实战经验
•
一紧张,连项目里真实做过的东西都讲不清
一次面试失利,也许就意味着和理想岗位失之交臂。
在你犹豫的这几年里, 找工作的成本越来越高:
•
一个部门、一个领导,可能坚持一年就被解散
•
一个项目,可能在10年、20年后, 曾经复杂的业务规则、先进的架构,早已被淘汰
•
市场上新的技术和面试要求,每年都在不断升级
等你回过头来,发现不仅机会没了, 连准备的方向都变了。
不是让你成为C++专家, 而是让你成为C++面试专家。
不是让你疯狂学习新知识, 而是帮你重新整理已有知识, 让你的能力与面试题精准对齐。
因为,21天就够了, 足够让我火力全开,
•
一边补齐 C++ 知识点,
•
一边刷爆经典面试题,
•
一边撸穿开源项目,
•
让自己变得不可替代!
让你学到每个 c++知识,都关联一个经典面试,并对对应开源项目实践
•
系统备战 每天 20~30 分钟,聚焦 C++ 核心知识, 三周时间完成高效梳理。
•
经典面试题 每个知识点都关联一个高频面试题, 让你知道“为什么考”和“怎么答”。
•
开源项目实践 通过真实项目理解底层原理, 不背答案,而是用实践打动面试官。
•
场景驱动学习 还原真实面试场景, 帮你学会“怎么说服面试官”。
•
三周后,面对面试官,你能自信说出: *“问吧,准备好了。”