C++ 11 const和constexpr关键字
const关键字和constexpr关键字的概念一直都没有分析的很清楚,今天稍微做了点研究,现总结如下。(事前声明,以下是对于C++11标准的理解,未定义行为不深究,本人水平有限如有错误请指出)
const关键字
cv (const and volatile) type qualifiers
Such object cannot be modified: attempt to do so directly is a compile-time error
const关键字修饰的对象是无法被修改的,任何对于该变量的修改都是会被编译期检查出并报错的。
and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.
如果你间接通过引用或者非const指针修改const对象的行为是未定义的。
这里我多说一句,看到很多网上讨论这种间接修改const对象的文章,我的理念是既然标准里没有定义这种行为,那么你就不要使用这种行为。如果发现你不得不要使用这种行为,那么我觉得是你程序设计的思路上和C++的设计者有区别,应该能够有更好的解决方案(例如不使用const关键字或者参考后面会介绍的mutable关键字)。
constexpr关键字
constexpr specifier (since C++11)
The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.
constexpr关键字声明表示函数返回的值和变量在编译器可能被求出。
constexpr可以修饰变量、函数返回值。
A constexpr specifier used in an object declaration implies const.
constexpr修饰的对象是隐式const的。
A constexpr specifier used in a function declaration implies inline.
constexpr修饰的函数是隐式内联的。
下面将详细讨论constexpr的行为。
constexpr 变量
一个constexpr变量要满足以下规则:
- 变量类型必须是字面值类型。
- 变量必须立即初始化
- 初始化表达式必须是常量表达式(也就是其值在编译期就可确定)
如果不满足以上条件那么编译期会直接报错。
constexpr函数
一个constexpr函数要满足:
- 不是virtual函数
- 每一个参数都必须是字面值
- 只能包含:空语句、静态断言、不声明类和枚举的typedef和alias语句、using语句,最重要的是有且只有一个return语句。
注意:一个constexpr函数只有在满足上述条件的情况下才能返回一个constexpr值否则其行为与一般函数相同。
const和constexpr
const的翻译是常量,consexpr是常值,从他们的名字就能体会其中的不同。常量是指其存在期间不可改变,但其实const变量的值是可以在程序运行中通过初始化决定的。而常值则是在程序编译期就确定了,在程序运行时,由于constexpr也是const的,所以其值也是一直固定的。