constexpr明确定义了编译阶段常量。
在栈上定义的数组,数组的长度必须是一个常量表达式:
- int ayy[17];//正确
- int ayy[7 + 4]; //正确
- int length = 8; int ayy[length]; //错误,length是变量
常量表达式
常量表达式和非常量表达式的计算时机不同:
- 非常量表达式是在程序运行阶段计算;
- 常量表达式是在程序的编译阶段计算,这提高了程序的执行效率,节省了每次程序运行时都需要计算一次的时间。
功能
constexpr 关键字的功能,是使指定的常量表达式,获得在程序编译阶段,计算出结果的能力,而不必等到程序运行阶段。constexpr 可用于修饰普通变量、函数(包括模板函数)以及类的构造函数。注意,不代表 constexpr 修饰的表达式一定会在程序编译阶段被执行,具体的计算时机还是编译器说了算。
constexpr int length = 6;
int ayy[length]; // OK
constexpr修饰函数
正确的定义 display() 常量表达式函数的写法:
constexpr int display(int x) {
//可以添加 using 执行、typedef 语句以及 static_assert 断言
return 1 + 2 + x;
}
可以看到,函数display() 的返回值,是用 constexpr 修饰的 int 类型值,且该函数的函数体中,只包含一个 return 语句。
该函数必须有返回值,即函数的返回值类型不能是 void。
constexpr 修饰类的构造函数时,要求该构造函数的函数体必须为空,且采用初始化列表的方式为各个成员赋值时,必须使用常量表达式。
//自定义类型的定义
class myType {
public:
constexpr myType(const char *name,int age):name(name),age(age){};
constexpr const char * getname(){
return name;
}
constexpr int getage(){
return age;
}
int old_getage() const{
return age;
}
private:
const char* name;
int age;
};
//模板函数
template<typename T>
constexpr T dispaly(T t){
return t;
}
与const区别
“const int x=5”只是想强调 x 是一个只读的变量,其本质仍为变量,无法用来初始化 array 容器;
而“constexpr int x =5”,表明 x 是一个只读变量的同时,x 还是一个值为 5 的常量,可以用来初始化 array 容器。
建议将 const 和 constexpr 的功能区分开,即凡是表达“只读”语义的场景都使用 const,表达“常量”语义的场景都使用 constexpr。
#include <iostream>
#include <array>
using namespace std;
constexpr int sqr1(int arg){
return arg*arg;
}
const int sqr2(int arg){
return arg*arg;
}
int main()
{
array<int,sqr1(10)> mylist1;//可以,因为sqr1时constexpr函数
array<int,sqr2(10)> mylist1;//不可以,因为sqr2不是constexpr函数
return 0;
}
const 用于为修饰的变量添加“只读”属性;而 constexpr 关键字则用于指明其后是一个常量(或者常量表达式),编译器在编译程序时可以顺带将其结果计算出来,而无需等到程序运行阶段,这样的优化极大地提高了程序的执行效率。
constexpr关键字允许在编译时计算表达式,并可用于定义数组长度等。它与const的区别在于,const变量是运行时的只读变量,而constexpr变量是编译时的常量表达式。constexpr可用于修饰函数和类的构造函数,要求函数体简单并仅包含常量表达式。在使用中,应根据需要选择const或constexpr以提高程序效率。
3412

被折叠的 条评论
为什么被折叠?



