本系列文章由 @yhl_leo 出品,转载请注明出处。

文章链接: http://blog.csdn.net/yhl_leo/article/details/50864210


关键字 constexpr 于 C++11 中引入并于 C++14 中得到改善。它表示常数表达式。与 const 相同,它可应用于变量,因此如果任何代码试图修改该值,均将引发编译器错误。与 const 不同,constexpr 也可应用于函数和类构造函数。 constexpr 指示值或返回值是常数,并且如果可能,将在编译时计算值或返回值。

1 constexpr 变量

constconstexpr 变量之间的主要区别在于:const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。所有 constexpr 变量均为常量,因此必须使用常量表达式初始化。

  1. constexpr float x = 42.0;
  2. constexpr float y{108};
  3. constexpr float z = exp(5, 3);
  4. constexpr int i; // Error! Not initialized
  5. int j = 0;
  6. constexpr int k = j + 1; //Error! j not a constant expression

一般来说,如果你认定变量是一个常量表达式,那就把它声明成为constexpr类型。

2 constexpr 函数

constexpr 函数是在使用需要它的代码时,可以在编译时计算其返回值的函数。当其参数为 constexpr 值并且在编译时使用代码需要返回值时(例如,初始化一个 constexpr 变量或提供一个非类型模板参数),它会生成编译时常量。使用非constexpr 参数调用时,或编译时不需要其值时,它将与正则函数一样,在运行时生成一个值。

  1. #include <iostream>
  2. using namespace std;
  3. // Pass by value
  4. constexpr float exp(float x, int n)
  5. {
  6. return n == 0 ? 1 :
  7. n % 2 == 0 ? exp(x * x, n / 2) :
  8. exp(x * x, (n - 1) / 2) * x;
  9. };
  10. // Pass by reference
  11. constexpr float exp2(const float& x, const int& n)
  12. {
  13. return n == 0 ? 1 :
  14. n % 2 == 0 ? exp2(x * x, n / 2) :
  15. exp2(x * x, (n - 1) / 2) * x;
  16. };
  17. // Compile time computation of array length
  18. template<typename T, int N>
  19. constexpr int length(const T(&ary)[N])
  20. {
  21. return N;
  22. }
  23. // Recursive constexpr function
  24. constexpr int fac(int n)
  25. {
  26. return n == 1 ? 1 : n*fac(n - 1);
  27. }
  28. // User-defined type
  29. class Foo
  30. {
  31. public:
  32. constexpr explicit Foo(int i) : _i(i) {}
  33. constexpr int GetValue()
  34. {
  35. return _i;
  36. }
  37. private:
  38. int _i;
  39. };
  40. int main()
  41. {
  42. // foo is const:
  43. constexpr Foo foo(5);
  44. // foo = Foo(6); // Error!
  45. //Compile time:
  46. constexpr float x = exp(5, 3);
  47. // const float a = 2.0;
  48. // const int b = 2;
  49. // constexpr float xx = exp2(a, b); // Error!
  50. constexpr float xx = exp2(2.0, 2);
  51. constexpr float y{ exp(2, 5) };
  52. constexpr int val = foo.GetValue();
  53. constexpr int f5 = fac(5);
  54. const int nums[]{ 1, 2, 3, 4 };
  55. const int nums2[length(nums) * 2]{ 1, 2, 3, 4, 5, 6, 7, 8 };
  56. cout << "The value of foo is " << foo.GetValue() << endl;
  57. }

3 constexpr和指针

还记得const与指针的规则吗?如果关键字const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针本身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。

const不同,在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指对象无关

  1. const int *p = 0; // non-const pointer, const data
  2. constexpr int *q = 0; // const pointer, non-const data

与其它常量指针类似,const指针既可以指向常量也可以指向一个非常量:

  1. int j = 0;
  2. constexpr int i = 2;
  3. constexpr const int *p = &i; // const pointer, const data
  4. constexpr int *p1 = &j; // const pointer, non-const data

C++ constexpr类型说明符的更多相关文章

  1. [C语言 - 1.2] 类型说明符、字符、数组

    A.类型说明符(只能修饰int) short int: = short 2字节 long int: long 8字节 = long   输出占位符 %ld signed int: = signed 默 ...

  2. Java final类&所有构造方法均为private的类(类型说明符&访问控制符)

    1. final是类型说明符,表示关闭继承,即final类不能有子类: 但final类可能可以在类外创建对象(即final类的构造方法可以不是private型): 在同一包中时,可以在任何另外一个类中 ...

  3. auto类型说明符的注意事项

    1.auto类型说明符,是C++11标准下的,它能让编译器自行判断表达式的类型. 2.auto也能在一条语句上声明多个变量,但是,该语句上的多个变量的类型,必须一致. 3.编译器推断出来auto类型可 ...

  4. C++11 auto类型说明符的使用

    编程的时候常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型.然而做到这一点很难,有时候根本做不到.为了解决这个问题.C++11新标准引入了auto类型说明符,用它就 能让编 ...

  5. C 进制 类型说明符 位运算 char类型

    一 进制 1. 什么是进制 是一种计数的方式 数值的表示形式 2. 二进制 1> 特点: 只有0和1 逢2进1 2> 书写格式: 0b或者0B开头 3> %d 以带符号的十进制形式输 ...

  6. 语法错误 : 缺少“;”(在“*”的前面) 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int

    sv2010编译的时候遇到错误: error C2143: 语法错误 : 缺少“;”(在“*”的前面) error C4430: 缺少类型说明符 - 假定为 int.注意: C++ 不支持默认 int ...

  7. C++ decltype类型说明符(尾置返回类型使用)

    转自https://blog.csdn.net/yhl_leo/article/details/50865552 1 基本语法 decltype 类型说明符生成指定表达式的类型.在此过程中,编译器分析 ...

  8. [Windows] 程序生成出现语法错误: 意外的令牌“标识符”,预期的令牌为“类型说明符”

    程序生成出现语法错误: 意外的令牌“标识符”,预期的令牌为“类型说明符” 将平台工具集改为VS 2015 (v140) ,重新编译即可

  9. (2)左右值初探与auto类型说明符

    这篇文章的起因是下面这两段代码,出自<C++ primer 5th>中文版P62页: auto &h =42;//错误,不能为非常量引用绑定字面值 const auto & ...

随机推荐

  1. andoid电阻触摸移植

    这里我使用的是210的开发板 系统Android4.0.4 内核linux3.0.8 要用电阻屏一般都是使用tslib进行校准的 这里给个我在android上用的tslib 下载地址 http://d ...

  2. Cocos2d-x《雷电大战》(3)-子弹无限发射

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现雷电游戏中,游戏一開始,英雄飞机就无限发射子弹的功能. 这里的思想是单独给子弹弄一个 ...

  3. RDLC报表钻取空白页问题

    在改动报表查询条件时,钻取页突然空白了,百思不得其解,之前好好的,研究了一个下午和一个晚上.查资料等等,网上非常多资料都是设置报表的 ConsumeConteinerWhitespace = True ...

  4. 委托delegate,Action,Func,Predicate

    C#委托的介绍(delegate.Action.Func.predicate) 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 ...

  5. 【BZOJ 2982】 combination

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2982 [算法] lucas定理 [代码] #include<bits/stdc ...

  6. day63-webservice 06.在web项目中发布以类的形式发布webservice

    真正用的时候都是需要部署在WEB服务器里面. 不能写主函数来发布了,需要借助于我们WEB. 4.配置web.xml, <!DOCTYPE web-app PUBLIC "-//Sun ...

  7. 用虚拟机创建win7 32位系统来测试win 7 64位系统无法安装cad 2004 缺少acdb16.dll的问题

  8. WPF中StringToImage和BoolToImage简单用法

    在WPF的绑定控件操作中,经常会通过bool值或者某些特定的string值做出相应动作.但UI层控件的很多属性对应的都不是Bool值或者对应的只是固定的String值. 这个时候有两方法解决该问题. ...

  9. HDU 2520 我是菜鸟我怕谁

    2019-05-27 17:52:01 加油!!! 看题时候就要仔细,最后容易忘记%10000 #include <bits/stdc++.h> using namespace std; ...

  10. king枚举帮助类

    可以方便的实现枚举 枚举 public enum DeptType { [Description("科室1")] Professional = , [Description(&qu ...