关于constexpr与const
来源:互联网 发布:微博淘宝版入口 编辑:程序博客网 时间:2024/06/06 00:49
C++之父是这样解释二者的:
const:大致意思是说我承诺不改变这个值,主要用于说明接口,这样变量传递给函数就不担心变量会在函数内被修改了编译器负责确认并执行const的承诺。
constexpr:大致意思是在编译时求值,主要用于说明常量,作用是允许数据置于只读内存以及提升性能。
按照这种说法,我的理解是const大多用于接口中,声明不对传入的参数做修改,而constexpr多用于编译时求值,需要编译时求值的大概就是数组边界声明(数组大小)、case标签、某些模版实参及使用constexpr的常量(cpp程序设计语言第四版-p37)
对于修饰Object来说,
const并未区分出编译期常量和运行期常量
constexpr限定在了编译期常量
基本含义/语法
const和constexpr都可以来修饰对象和函数。
修饰对象的时候两者之间最基本的区别是:
const修饰一个对象表示它是常量。这暗示对象一经初始化就不会再变动了,并且允许编译器使用这个特点优化程序。这也防止程序员修改了本不应该修改的对象。
constexpr是修饰一个常量表达式。但请注意constexpr不是修饰常量表达式的唯一途径。
修饰函数的时候两者之间最基本的区别是:
1.const只能用于非静态成员的函数(静态成员函数并不包含this指针,也就不存在const来修饰他了)而不是所有函数。它保证成员函数不修改任何非静态数据。
2.constexpr可以用于含参和无参函数。constexpr函数适用于常量表达式,只有在下面的情况下编译器才会接受constexpr函数:
a.函数体必须足够简单,除了typedef和静态元素,只允许有return语句。如构造函数只能有初始化列表,typedef和静态元素 (实际上在C++14标准中已经允许定义语句存在于constexpr函数体内了)
b.参数和返回值必须是字面值类型
常量表达式
常量表达式的概念如下
必须是可以在编译阶段被识别的。比如模版的参数/数组的大小。
1.template <int N>class fixed_size_list{ /*...*/ };2.fixed_size_list<X> mylist; //X必须是字面值类型3.int numbers[X]; // X必须是字面值类型
但是注意下面两点
用constexpr修饰某物并不保证它一定在编译时被计算,也可以在运行时被计算。
不用constexpr也可能是一个常量表达式,如
int main(){const int N = 3;int num[N] = {1,2,3,};//N是一个常量表达式}//N在声明时初始化,满足常量表达式的标准,虽然没用constexpr
所以到底什么时候用constexpr?
像上面的N,虽然没有用 constexpr 仍然是一个常量表达式。事实上,const本身和它的枚举类型若在声明时初始化那么就是一个常量表达式。
在函数中若有常量表达式那么必须用constexpr,仅仅满足常量表达式的条件是不够的,如
template <int N>class list{ };constexpr int sqr1(int arg){ return arg*arg; }int sqr2(int arg){ return arg*arg; }int main(){const int X = 2;list<sqr1(X)> mylist1;//可以,因为sqr1时constexpr函数list<sqr2(X)> mylist2;//不可以,因为sqr2不是constexpr函数return 0;}
什么时候该同时使用两者?
在修饰变量的时候
修饰变量时没有必要同时使用const和constexpr 因为constexpr包含了 const的含义
constexpr const int N = 5;constexpr int N = 5;//两行的意思完全相同
然而注意有一些情况const和constexpr在修饰不同的东西,比如
static constexpr int N = 3;int main(){ constexpr const int *NP = &N return 0;}
在这里constexpr和const都必须要有。constexpr表示NP指针本身是常量表达式,而const表示指向的值是一个常量。去掉const之后无法编译,因为不能用普通指针指向常量。
在修饰成员函数的时候
在C++11中,对成员函数而言constexpr同样包含const的含义。然而在C++14中可能已经改变了。如
constexpr void f();
以后可能必须写成
constexpr void f() const;
虽然目前写成const仍然有效,但最好使用constexpr来防止以后修改大量代码的可能性。
//(以上部分来自知乎、维基及博客)
- 关于constexpr与const
- const与constexpr
- const与constexpr
- 常量表达式与const和constexpr
- const,constexpr与指针,常量表达式
- 2.4Const限定符(const初始化,const与引用,const与指针,const指针,顶层const,constexpr)
- C++ const引用,指针,constexpr
- c++的const和constexpr
- C++中的const和constexpr
- const引用const指针以及constexpr
- 指正与constexpr
- const限定符和constexpr初探
- C++总结:C++中的const和constexpr
- 关于引用与const
- 关于const与指针
- 关于static与const
- constexpr
- constexpr
- Centos7.x更新到最新版后无法直接使用Metasploit的解决方案
- Unity 接广点通
- Android开发 之 设计模式MVP
- webpack中的path和publicPath的作用
- Android开发过程中设置阴影
- 关于constexpr与const
- 程序员提高效率的辅助开发软件神器汇总
- IDEA和svn进行关联
- 【送谷歌定制礼品】一起寻找最初的写作热忱 即刻动笔!
- App Store 下载软件提示连接超时,无法购买
- 终端模拟器Xshell中怎么保存日志
- 【大神谈】我是怎么招聘程序员的
- EAGLE电路设计:用NET工具简化元件间的连线
- linux bash 脚本获取git当前的分支名