C ++编程语言第四版 - Bjarne Stroustrup :(强调我的)
2.2.3。常数
在一些地方,语言规则需要常量表达式 (例如,数组边界(§2.2.5,§7.3),案例标签(§2.2.4,§9.4.2),一些 模板参数(第25.2节)和使用constexpr声明的常量。 在其他情况下,编译时评估对性能很重要。 独立于性能问题,不可变性(具有不可更改状态的对象)的概念是一个重要的设计问题 (第10.4节)。
似乎Stroustrup在此建议constexpr
确保对象的不变性优于传统的const
声明。它是否正确?有哪些方法constexpr
可以比const
更安全/更不稳定,或者Stroustrup是否只是意味着因为有constexpr
方法可以使用const
不支持(请参阅 Is constexpr really needed? ),在这些情况下,使用constexpr
可以确保不变性吗?
答案 0 :(得分:10)
他在本节的开头说:
C ++支持两种不变性概念
他列出了 const 和 constexpr ,我不相信他会试图说 constexpr 比更能确保不变性const 他们只是有不同的功能,虽然我承认句子引用部分10.4
常量表达式的事实似乎暗示,这种解释与文本的其余部分不一致。
const
变量在该范围内是不可变的,但在较大范围内可能不是const
(例如函数的const引用参数)也许是他试图做出的微妙区别,他说const
:
主要用于指定接口
而constexpr
:
这主要用于指定常量,以允许在只读存储器中放置数据
constexpr
的任何变量都应该在编译时进行评估,因此在需要常量表达式时可用,而作为const
传递给函数的变量不必是{{1}在那个范围之外。
当然你可以使用const
抛弃 constness 但是尝试修改const_cast
对象是未定义的行为,因此它不会比const
中的constexpr
更不可变。这感觉来自draft C++11 standard部分7.1.6.1
cv-qualifiers :
任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为
Jonathan Wakely指出,像 const 变量这样的 constexpr 变量可以有一个mutable member,但该成员不能用于常量表达式。
请注意, constexpr 变量也是 const ,来自草案C ++ 11标准部分7.1.5
constexpr说明符 :
对象声明中使用的constexpr说明符声明了 对象为常量。
答案 1 :(得分:5)
const
不能确保按位常数,例如因为类可以有可变成员(典型的例子是用于内部同步的私有互斥体),你可以从指针中const_cast
消除常量。
constexpr
声明一个可以在编译时计算的常量变量或函数,这意味着对象的内容有一些限制,但我相信,关键字本身在运行时没有提供任何额外的保证。到const
。
另请参阅this讨论。