constexpr更多"常数"比const?

时间:2014-12-01 04:51:39

标签: c++11 const immutability constexpr

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可以确保不变性吗?

2 个答案:

答案 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讨论。