行业知识
【C++】const与constexpr详解
参考:
()- C++11 constexpr:验证是否为常量表达式(长篇神文)
- C++11 constexpr和const的区别详解
- constexpr
1. constexpr:常量表达式
���谓常量表达式,指的就是由多个(≥1)常量组成的表达式。换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。这也意味着,常量表达式一旦确定,其值将无法修改。
实际开发中,我们经常会用到常量表达式。以定义数组为例,数组的长度就必须是一个常量表达式:
()// 1)int url[10];//正确// 2)int url[6 + 4];//正确// 3)int length = 6;int url[length];//错误,length是变量
上述代码演示了 3 种定义 url 数组的方式,其中第 1、2 种定义 url 数组时,长度分别为 10 和 6+4,显然它们都是常量表达式,可以用于表示数组的长度;第 3 种 url 数组的长度为 length,它是变量而非常量,因此不是一个常量表达式,无法用于表示数组的长度。
常量表达式的应用场景还有很多,比如匿名枚举、switch-case 结构中的 case 表达式等,感兴趣的读者可自行编码测试,这里不再过多举例。
我们知道,C++ 程序的执行过程大致要经历编译、链接、运行这 3 个阶段。值得一提的是,常量表达式和非常量表达式的计算时机不同,非常量表达式只能在程序运行阶段计算出结果;而常量表达式的计算往往发生在程序的编译阶段,这可以极大提高程序的执行效率,因为表达式只需要在编译阶段计算一次,节省了每次程序运行时都需要计算一次的时间。
对于用 C++ 编写的程序,性能往往是永恒的追求。那么在实际开发中,如何才能判定一个表达式是否为常量表达式,进而获得在编译阶段即可执行的“特权”呢?除了人为判定外,C++11 标准还提供有 constexpr 关键字。
constexpr 关键字的功能是使指定的常量表达式获得在程序编译阶段计算出结果的能力,而不必等到程序运行阶段。C++ 11 标准中,constexpr 可用于修饰普通变量、函数(包括模板函数)以及类的构造函数。
注意:获得在编译阶段计算出结果的能力,并不代表 constexpr修饰的表达式一定会在程序编译阶段被执行,具体的计算时机还是编译器说了算。
1.1 constexpr修饰普通变量
C++11 标准中,定义变量时可以用 constexpr 修饰,从而使该变量获得在编译阶段即可计算出结果的能力。
注意:使用 constexpr 修改普通变量时,变量必须经过初始化且初始值必须是一个常量表达式。举个例子:
#include using namespace std;int main(){ constexpr int num = 1 + 2 + 3; int url[num] = {1,2,3,4,5,6}; couts int ret = 1 + 2 + x; return ret;} //可以添加 using 执行、typedef 语句以及 static_assert 断言 return 1 + 2 + x;} //函数体} return 1 + 2 + x;}int main(){ //调用常量表达式函数 int a[display(3)] = { 1,2,3,4 }; cout return 1 + 2 + x;} return num + x;}int main(){ //调用常量表达式函数 int a[display(3)] = { 1,2,3,4 }; return 0;} const char* name; int age; //其它结构体成员};int main(){ constexpr struct myType mt{ "zhangsan", 10 }; cout constexpr myType(char *name,int age):name(name),age(age){}; const char* name; int age; //其它结构体成员};int main(){ constexpr struct myType mt { "zhangsan", 10 }; cout public: constexpr myType(const char *name,int age):name(name),age(age){}; constexpr const char * getname(){ return name; } constexpr int getage(){ return age; }private: const char* name; int age; //其它结构体成员};int main(){ constexpr struct myType mt { "zhangsan", 10 }; constexpr const char * name = mt.getname(); constexpr int age = mt.getage(); cout const char* name; int age; //其它结构体成员};//模板函数template return t;}int main(){ struct myType stu{"zhangsan",10}; //普通函数 struct myType ret = dispaly(stu); cout //错误,x是只读的变量 array 1,2,3,4,5}; cout const int x = 5; array 1,2,3,4,5}; cout dis_1(5); dis_2();} int a = 10; const int & con_b = a; cout return arg*arg;}const int sqr2(int arg){ return arg*arg;}int main(){ array
上一篇:电脑怎么上云服务器地址?