一个 constexpr 比 const 更"constant"吗?

Is a constexpr more "constant" than const?

本文关键字:constant constexpr const 一个      更新时间:2023-10-16

The C++ Programming Language Fourth Edition - Bjarne Stroustrup:(强调我的(

2.2.3. 常量

在一些地方,语言规则需要常量表达式 (例如,数组边界(§2.2.5,§7.3(,大小写标签(§2.2.4,§9.4.2(,一些 模板参数 (§25.2(,以及使用 constexpr 声明的常量(。 在其他情况下,编译时评估对于性能很重要。 与性能问题无关,不可变性(具有不可更改状态的对象(的概念是一个重要的设计问题 (§10.4(。

Stroustrup似乎在这里暗示,constexpr比传统的const声明更能确保对象的不变性。这是对的吗?有没有办法constexprconst更安全/更不易失性,或者Stroustrup只是意味着,由于有一些方法可以使用const不支持的constexpr(参见 constexpr 真的需要吗?(,在这些情况下可以使用 constexpr 来确保不变性?

他在本节开头说:

C++支持两个不变性概念

他列出了 const 和 constexpr,我不相信他试图说 constexprconst 更好地确保不变性,它们只是具有不同的功能,尽管我承认这句话引用了常量表达式10.4部分这一事实似乎确实暗示了这一点,这种解释与文本的其余部分不一致。

const变量在该作用域中是不可变的,但在更大的作用域中可能不会const(例如函数的常量引用参数(,这可能是他试图做出的微妙区别,他说const

主要用于指定接口

constexpr

这主要用于指定常量,以允许将数据放置在只读内存中

任何constexpr变量都应该在编译时计算,因此在需要常量表达式的情况下可用,而作为const传递给函数的变量不必在该范围之外const

当然,您可以使用const_cast抛弃恒常性,但尝试修改const对象是未定义的行为,因此从这个意义上说,它的不可变性不constexpr亚于从 C++11 标准部分草案中7.1.6.1 cv 限定符

在 const 对象的生存期 (3.8( 期间修改该对象的任何尝试都会导致未定义的行为

Jonathan Wakely 指出,像 const 变量这样的 constexpr 变量可以有一个可变成员,但该成员不能在常量表达式中使用。

请注意,constexpr 变量也是 consst,来自草案 C++11 标准部分7.1.5 constexpr 说明符

对象声明中使用的 constexpr 说明符声明 对象作为常量。

>const不能确保按位恒常性,例如,因为类可以有可变成员(典型的例子是用于内部同步的私有互斥锁(,你可以从指针中const_cast恒常性。

constexpr声明了一个可以在编译时计算的常量变量或函数,这意味着对对象可以是什么有一些限制,但我相信,与const相比,关键字本身在运行时不提供任何额外的保证。另请参阅此讨论。