You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对《C++编程原理与实践》中constexpr示例正确性的疑问及修正探讨

你的判断完全正确,书中示例确实存在错误

首先,我们来明确C++标准中关于constexpr变量初始化的核心规则:

  • 要初始化一个constexpr变量,其初始化器必须是常量表达式。
  • 若要在常量表达式中使用一个对象,该对象必须是constexpr声明的,或者是const类型且由常量表达式初始化的(对于自动变量而言,仅const还不够,必须确保其值在编译期完全可知)。

回到书中的示例代码:

void user(Point p1) {
Point p2 {10,10};
Point p3 = scale(p1); // OK: p3 == {100,8}; 运行时求值可行
constexpr Point p4 = scale(p2); // p4 == {100,8}
constexpr Point p5 = scale(p1); // error: scale(p1)不是常量表达式
constexpr Point p6 = scale(p2); // p6 == {100,8}
// . . .
}

这里的问题出在p2的声明上:它只是一个普通的自动变量,既没有constexpr也没有const修饰。哪怕它是用字面量10,10初始化的,它的存储属于运行时范畴,其值无法被常量表达式的编译期求值过程访问。因此constexpr Point p4 = scale(p2);和constexpr Point p6 = scale(p2);这两行代码必然会触发编译错误,和p5的错误原因本质一致——scale(p2)无法在编译时完成求值。

修正后的正确代码

void user(Point p1) {
    constexpr Point p2 {10,10}; // 必须添加constexpr修饰
    Point p3 = scale(p1); // OK: 运行时求值可行
    constexpr Point p4 = scale(p2); // OK: 编译期求值
    constexpr Point p5 = scale(p1); // error: scale(p1)不是常量表达式
    constexpr Point p6 = scale(p2); // OK: 编译期求值
    // . . .
}

这种情况大概率是书中的笔误,作为C++的设计者,Stroustrup不可能不清楚常量表达式的规则,应该是编写示例时遗漏了constexpr修饰符。

内容的提问来源于stack exchange,提问作者Maestro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:59:10