设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 数据 手机 公司
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++11 constexpr 验证是不是为常量表达式

发布时间:2022-07-13 11:22 所属栏目:51 来源:互联网
导读:constexpr 是 C++ 11 标准新引入的关键字,不过在讲解其具体用法和功能之前,读者需要先搞清楚 C++ 常量表达式的含义。 所谓常量表达式,指的就是由多个(1)常量组成的表达式。换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。这也
  constexpr 是 C++ 11 标准新引入的关键字,不过在讲解其具体用法和功能之前,读者需要先搞清楚 C++ 常量表达式的含义。
 
  所谓常量表达式,指的就是由多个(≥1)常量组成的表达式。换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。这也意味着,常量表达式一旦确定,其值将无法修改。
  
  读者可尝试将 constexpr 删除,此时编译器会提示“url[num] 定义中 num 不可用作常量”。
 
  可以看到,程序第 6 行使用 constexpr 修饰 num 变量,同时将 "1+2+3" 这个常量表达式赋值给 num。由此,编译器就可以在编译时期对 num 这个表达式进行计算,因为 num 可以作为定义数组时的长度。
 
  有读者可能发现,将此示例程序中的 constexpr 用 const 关键字替换也可以正常执行,这是因为 num 的定义同时满足“num 是 const 常量且使用常量表达式为其初始化”这 2 个条件,由此编译器会认定 num 是一个常量表达式。
  注意,const 和 constexpr 并不相同,关于它们的区别,我们会在下一节做详细讲解。
 
  另外需要重点提出的是,当常量表达式中包含浮点数时,考虑到程序编译和运行所在的系统环境可能不同,常量表达式在编译阶段和运行阶段计算出的结果精度很可能会受到影响,因此 C++11 标准规定,浮点常量表达式在编译阶段计算的精度要至少等于(或者高于)运行阶段计算出的精度。
  constexpr修饰函数
  constexpr 还可以用于修饰函数的返回值,这样的函数又称为“常量表达式函数”。
 
  注意,constexpr 并非可以修改任意函数的返回值。换句话说,一个函数要想成为常量表达式函数,必须满足如下 4 个条件。
 
  1) 整个函数的函数体中,除了可以包含 using 指令、typedef 语句以及 static_assert 断言外,只能包含一条 return 返回语句。
 
  举个例子:
  constexpr int display(int x) {
      int ret = 1 + 2 + x;
      return ret;
  }
  注意,这个函数是无法通过编译的,因为该函数的返回值用 constexpr 修饰,但函数内部包含多条语句。
 
  如下是正确的定义 display() 常量表达式函数的写法:
  constexpr int display(int x) {
      //可以添加 using 执行、typedef 语句以及 static_assert 断言
      return 1 + 2 + x;
  }
  可以看到,display() 函数的返回值是用 constexpr 修饰的 int 类型值,且该函数的函数体中只包含一个 return 语句。
 
  2) 该函数必须有返回值,即函数的返回值类型不能是 void。
 
  举个例子:
  constexpr void display() {
      //函数体
  }
  像上面这样定义的返回值类型为 void 的函数,不属于常量表达式函数。原因很简单,因为通过类似的函数根本无法获得一个常量。
 
  3) 函数在使用之前,必须有对应的定义语句。我们知道,函数的使用分为“声明”和“定义”两部分,普通的函数调用只需要提前写好该函数的声明部分即可(函数的定义部分可以放在调用位置之后甚至其它文件中),但常量表达式函数在使用前,必须要有该函数的定义。
 

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读