const
constexpr函数(函数是常量表达式)
1、constexpr让编译器确定一个变量是不是常量表达式,是属于编译期常量。
2、返回值和参数必须是Literal类型(常量)
3、函数体必须只包含一个return语句
4、函数提可以包含其他的语句,但是这些语句不能在运行期起作用
5、函数可以不返回常量,但是在调用的时候实参必须传入常量表达式
constexpr 修饰的变量表示常量表达式(const expression):是指值不会改变并且在编译过程中就得到计算结果的表达式。constexpr常量表达式不光该值本身不能变,就是该值右边的赋值表达式都必须是常量的。
这样限制度更高安全性更强。
const int i=3; //是一个常量表达式
const int j=i+1; //是一个常量表达式
constexpr int i=3;//是一个常量表达式
constexpr int j=i+1;//是一个常量表达式
constexpr int k=f(); //f()返回值需要是一个constexpr,是一个常量表达式
constexpr变量:
C++11允许声明constexpr类型来由编译器检验变量的值是否是一个常量表达式。声明为constexpr的必须是一个常量,并且只能用常量或者常量表达式来初始化。
一般来说,若果一旦认定变量是一个常量表达式,那就把它声明为constexpr类型
尽管指针和引用都可以定义为constexpr,但是他们的初始值却受到了严格的限制。一个constexpr指针的初始值必须是nullptr或者0,或者是存储某个固定地址的对象。函数体中定义的变量并非存放在固定地址中,因此constexpr指针不可以指向这样的变量。相反的,对于所有函数体之外的对象地址是固定不变的,可以用constexpr来定义;
必须明确一点,在constexpr声明中,如果定义了一个指针,限定符号constexpr仅仅对指针有效,与指针所指对象无关。
const int *p=nullptr; //p是一个指向整型常量的指针(pointer to const)
constexpr int *p1=nullptr; //p1是一个常量指针(const pointer)
PS:定义为constexpr类型的函数隐式的都为内联函数(inline)
#include <iostream>
using namespace std;
constexpr int new_size()
{
return 42;
}
constexpr size_t constexpr_scale(size_t arg)
//const size_t scale(size_t arg) //去掉constexpr或者将constexpr改成const 都会报错
{
return new_size() * arg;//new_size也必须是常量表达式
}
//const size_t scale(size_t arg) //也ok
size_t scale(size_t arg)
{
return new_size() * arg;
}
int main()
{
constexpr int constexpr_sz = constexpr_scale(2); //正确
int i = 2;
//constexpr int constexpr_sz_1= constexpr_scale(i);//会报错
const int b = scale(i);
const int c = constexpr_scale(i);
const int i2 = 3; //是一个常量表达式
const int j2 = i2 + 1; //是一个常量表达式
constexpr int constexpr_sz_2 = constexpr_scale(j2);
constexpr int i3 = 3;
constexpr int j3 = i3 + 1;
constexpr int constexpr_sz_3 = constexpr_scale(j3);
//constexpr_sz_3 = 2;//错误 不可以改
int a1 = 3;
//constexpr int* p1 = &a1;//报错
const int a2 = 3;
//constexpr int* p2 = &a2;//报错
constexpr int a3 = 3;
//constexpr int* p3 = &a3;//报错. constexpr int*是 int* const
int a4 = 3;
const int* p4= nullptr;//*p是常量
p4 = &a4;
//*p4 = 3;//报错
a4 = 3;//可以
int a5 = 3;
int* const p5 = &a5;
//constexpr int* p6 = p5;//错误
const int a6 = 3;
//int* const p7 = &a6;//错误
//constexpr int* p8 = p7;//错误
constexpr int a7 = 3;
//int* constexpr p9 = &a7;//错误
//constexpr int* p10 = p9;//错误
constexpr int a8 = 3;
//int* constexpr p9 = &a7;//错误
//constexpr int* p10 = &a8;//错误 int* constexpr 不存在
//constexpr int*是 int* const必须用数值或者对象的地址来赋值
system("pause");
return 0;
}
参考:
https://blog.csdn.net/csxiaoshui/article/details/39473419?t=1500799068105
https://www.cnblogs.com/td15980891505/p/5137013.html
http://blog.guorongfei.com/2018/03/14/cpp-const/
https://www.zhihu.com/question/35614219
https://www.zhihu.com/question/310728076
https://www.cnblogs.com/cauchy007/p/4966067.html