13、C++11 constexpr:验证是否为常量表达式

本文深入探讨了C++中的constexpr关键字,讲解了常量表达式的概念和作用。constexpr可以确保变量、函数和构造函数在编译时计算,提升程序效率。文章列举了constexpr修饰变量、函数和类构造函数的规则,并通过示例展示了其用法和限制条件。同时,还提到了constexpr在模板函数中的应用。
摘要由CSDN通过智能技术生成

所谓常量表达式,指的就是由多个(≥1常量 组成的表达式。

  • 如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。
  • 常量表达式一旦确定,其值将无法修改。
// 1)
int url[10];//正确
// 2)
int url[6 + 4];//正确
// 3)
int length = 6;
int url[length];//错误,length是变量

非常量表达式只能在程序运行阶段计算出结果;而常量表达式的计算往往发生在程序的编译阶段

常量表达式的计算往往发生在程序的编译阶段,这可以极大提高程序的执行效率,因为表达式只需要在编译阶段计算一次,节省了每次程序运行时都需要计算一次的时间。

constexpr 关键字的功能是 使指定的常量表达式获得在程序编译阶段计算出结果的能力,而不必等到程序运行阶段。

  • constexpr可以用于修饰变量、函数(包括模板函数)以及类的构造函数。
  • 注意,获得在编译阶段计算出结果的能力,并不代表 constexpr 修饰的表达式一定会在程序编译阶段被执行,具体的计算时机还是编译器说了算。

constexpr修饰普通变量

使用 constexpr 修改普通变量时,变量必须经过初始化且 初始值必须是一个常量表达式

int main()
{
    constexpr int num = 1+2+3;  //num经过初始化、初始值也是常量表达式
    int url[num] = {1,2,3,4,5,6};  //num如果不定义为constexpr,编译器会报错。
    return 0;
}
  • 这里constexper用const代替也行。
  • 但const 和 constexpr 并不相同。

constexpr修饰函数

constexpr 还可以用于修饰函数的返回值,这样的函数又称为“常量表达式函数”。

constexpr 并非可以修改任意函数的返回值。换句话说,一个函数要想成为常量表达式函数,必须满足如下 4 个条件:

  • 1) 整个函数的函数体中,除了可以包含 using 指令、typedef 语句以及 static_assert 断言外,只能包含一条 return 返回语句。

    constexpr int display(int x) {
        //可以添加 using 执行、typedef 语句以及 static_assert 断言
        return 1 + 2 + x;
    }
    
  • 2)该函数必须有返回值,即函数的返回值类型不能是 void。

    constexpr void display() { //返回值类型为 void 的函数,不属于常量表达式函数。
        //函数体
    }
    
  • 3)函数在使用之前,必须有对应的定义语句。

    • 普通的函数调用只需要提前写好该函数的声明部分即可(函数的定义部分可以放在调用位置之后甚至其它文件中),但常量表达式函数在使用前,必须要有该函数的定义。

    • #include <iostream>
      using namespace std;
      //普通函数的声明
      int noconst_dis(int x);
      //常量表达式函数的声明
      constexpr int display(int x);
      //常量表达式函数的定义
      constexpr int display(int x){
          return 1 + 2 + x;
      }
      int main()
      {
          //调用常量表达式函数
          int a[display(3)] = { 1,2,3,4 };
          cout << a[2] << endl;
          //调用普通函数
          cout << noconst_dis(3) << endl;
          return 0;
      }
      //普通函数的定义
      int noconst_dis(int x) {
          return 1 + 2 + x;
      }
      
      
  • 4) return 返回的表达式必须是常量表达式。

    #include <iostream>
    using namespace std;
    int num = 3;
    constexpr int display(int x){
        return num + x;    // num + x 不是常量表达式,编译器会报错
    }
    int main()
    {
        //调用常量表达式函数
        int a[display(3)] = { 1,2,3,4 };
        return 0;
    }
    

constexpr修饰类的构造函数

constexpr可以修饰C++ 内置类型的数据。但不能修饰自定义的数据类型。

  • 1) 修饰构造函数

    struct myType{
        constexpr myType(char* name, int age):name(name),age(age){}; //要求该构造函数的函数体必须为空,
        															//且采用初始化列表的方式为各个成员赋值时,必须使用常量表达式。   
    }
    
  • 2)修饰成员函数

    • 类中的成员函数必须满足前面提到的 4 个条件。

constexpr修饰模板函数

C++11 标准规定,如果 constexpr 修饰的模板函数实例化结果不满足常量表达式函数的要求,则 constexpr 会被自动忽略,即该函数就等同于一个普通函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值