constexpr变量

字面值类型包括算术类型、引用、指针、枚举和数据成员都是字面值类型的聚合类。

聚合类的定义:

所有成员都是public的。
    没有定义任何构造函数。
    没有类内初始值。
    没有基类,也没有虚函数。

如:

struct Data {
    int ival;
    string str;
};

1
    2
    3
    4

如果一个类不是聚合类,但它符合下述要求,则它也是一个字面值常量类:

数据成员必须是字面值类型
    类必须有一个constexpr构造函数
    如果一个数据成员含有类内初始值,则内置类型成员的初始值必须是一条常量表达式(其定义见下文);或者如果成员属于某种类类型,则初始值必须使用成员自己的constexpr构造函数
    类必须使用构造函数的默认定义

常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。

const int max_files=20;                 // max_files是常量表达式
const int limit=max_files+1;        //limit是常量表达式
int staff_size =27;                 // staff_size不是常量表达式
const int sz=get_size();            // sz不是常量表达式

1
    2
    3
    4
    5

尽管staff_size的初始始是个字面值常量,但由于它的数据类型非const,所以它不是常量表达式。尽管sz本身是一个常量,但它的具体值直到运行时才能得到,也不是常量表达式。

在一个复杂的系统中,很难分辨一个初始值到底是不是常量表达式。当然可以定义一个const变量并把它的初始值设为我们认为的某个常量表达式,但在实际使用中,尽管要求如此却常常发现初始值并非常量表达式的情况。

C++11规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。

constexpr int mf=20;        //20是常量表达式
constexper int limit=mf+1;    //mf+1是常量表达式
constxper int sz=size();    //只有当size是一个constxper函数时才是一条正确的声明语句

1
    2
    3

不能用普通函数作为constexpr变量的初始值,只能用constexpr函数去初始化constexpr变量。这种函数足够简单,以使得编译时就可以计算其结果。

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

constexpr函数是指能用于常量表达式的函数。该函数要遵循几项约定:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句:

constexpr int new_sz() { return 42; }
constexpr int foo = new_sz();

1
    2

在对变量foo初始化时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式地指定为内联函数。

constexpr函数体内也可以包含其它语句,只要这些语句在运行时不执行任何操作就行。例如,constexpr函数中可以有空语句、类型别名以及using声明。

需要注意的是,我们允许constexpr函数的返回值并非一个常量:

//如果arg是常量表达式,则scale(arg)也是常量表达式
constexpr size_t scale(size_t cnt){ return new_sz() * cnt; }

1
    2

当scale的实参是常量表达式时,它的表达式也是常量表达式,反之则不然:

int arr[scale(2)];    //正确:scale(2)是常量表达式
int i = 2;            //i不是常量表达式
int a2[scale(i)];    //错误:scale(i)不是常量表达式

1
    2
    3

当把scale函数用在需要常量表达式的上下文中时,如果其结果恰好不是常量表达式,编译器将发出错误信息。

注意,我们要把内联函数和constexpr函数定义在头文件中。因为内链函数是内部链接的,如果你在b.cpp中定义这个函数,那么在a.cpp中即使有这个函数声明,但由于内联函数是内部链接的,所以b.cpp不会提供其定义。所以在链接时a.obj无法找到这个函数的定义,便会出现无法解析的外部符号的错误
constexpr构造函数

我们知道,构造函数不能是const的。因为当我们创建一个类的const对象时,直到构造函数完成初始化过程,对象才能真正取得其”常量“属性。因此,构造函数在const对象的构造过程中可以可以向其写值。但是字面值常量类的构造函数可以是constexpr函数。事件上,一个字面值常量类必须至少提供一个constexpr函数。

constexpr构造函数可以声明成=default的形式(或者是删除函数的形式)。否则,constexpr构造函数体一般来说应该是空的,因为构造函数不能包含返回语句,而constexpr函数的唯一可执行语句就是返回语句。constexpr构造函数的声明形式如下:

class Debug {
public:
    constexpr Debug(int i) :i_(i) {}
private:
    int i_;
};

1
    2
    3
    4
    5
    6

constexpr构造函数必须初始化所有数据成员,初始值或者使用constexpr构造函数,或者是一条常量表达式。

————————————————
版权声明:本文为CSDN博主「freshman94」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_22660775/article/details/89336997

C++ 11 新特性: constexpr变量和constexpr函数相关推荐

  1. C++ 11 新特性(十二)函数新特性、内联函数、const详解

    函数后置返回类型 //后置返回类型 auto fun(int, int)->int; 内联函数 在函数定义前增加关键字 inline ,使得该函数变成内联函数 (1) 适用于函数体很小,调用很频 ...

  2. c++11新特性的使用---可变模板参数、type_traits、function综合使用

    DLL帮助类 c++中手动调用dll是比较繁琐的,调用过程是:加载dll后还要定义一个对应的函数指针类型,接着调用GetProAddress获取函数地址,在转成函数指针,最后调用该函数如下例子: #i ...

  3. C++11新特性之新类型与初始化

    C++11新特性之新类型与初始化 snoone | 2016-06-23 11:57    浏览量(148)    评论(0)   推荐(0) 数据 这是C++11新特性介绍的第一部分,比较简单易懂, ...

  4. C++11 新特性简介

    1.auto auto是旧关键字,在C++11之前,auto用来声明自动变量,表明变量存储在栈,很少使用.在C++11中被赋予了新的含义和作用,用于类型推断. auto关键字主要有两种用途:一是在变量 ...

  5. 【C++面试宝典】C++11新特性知识总结

    目录 C++11新特性 auto自动类型推导 decltype类型指示符 nullptr常量 lambda表达式(匿名函数) 智能指针 auto_ptr unique_ptr shared_ptr w ...

  6. A Morden C++ —— C++11新特性指南

    A Morden C++ -- C++11新特性指南 by JOKER on 2013/10/14 不知不觉C++1x,也就是以前的C++0x已经基本达到工业使用的成熟度了,各个编译器的实现也很完整了 ...

  7. C++11新特性(原封不动转载待查)

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  8. 【C++】C++11新特性列表

    我们学习的标准是C++98,我们知道计算机的知识更新非常快,本文旨在大致了解C++11的新特性,如果想要仔细了解,请阅读<C++Primer中文版 第五版>本文的页码也是这本书的页码,这里 ...

  9. IntelliJ IDEA 使用 Java 11新特性以及Java 8 以来的Java 11新特性介绍

    文章目录 Java 11 安装 IDEA 设置 特性1:lambda表达式中允许使用var 特性2: String新增REPEAT 方法,方便拷贝字符串 特性3: 文件读写更方便:readString ...

最新文章

  1. WPF 支持分组互斥的 RadioButton 式单选菜单
  2. 多问问自己想成为什么样的人
  3. LiveVideoStackCon深圳-网络的研究够搞个几辈子
  4. 在24小时内学完所有的数学是种什么体验?我们做了这个大胆的尝试……
  5. python 字符串删除重复_Python删除list里的重复元素有几种方法?
  6. mvp模式 php,Hyper-V - 增强会话模式
  7. 专访勒索组织“范本”:Thedarkoverlord 喜欢并享受辽阔的狩猎场
  8. lisp方格网法计算土方量_飞时达土方软件多级边坡土方量计算(选方格点放坡)...
  9. 怎么获取jquery版本_获取jQuery版本
  10. 一文彻底搞懂激光雷达原理!
  11. 从零搭建 ES 搜索服务(五)搜索结果高亮
  12. 天线和频率(波长)关系
  13. SQL - 数据查询语句之字符串拆分
  14. 桌面没计算机图标不见了怎么办,桌面图标不见了怎么办,详细教您电脑桌面图标不见了怎么办...
  15. 怎样修心?不乱于心,不困于情。
  16. 圆形标定板_自己改的,圆形标定板,opencv标定代码
  17. TCP/TP OSI7层模型和TCP/TP4层模型
  18. 异或、异或和 的性质及应用总结
  19. 网络协议——七层、五层、四层协议概念
  20. DICOM:开源DICOM服务框架DCM4CHE 构建

热门文章

  1. python 数据结构-字典
  2. 通过Log4net来配置我们需要的日志文件格式
  3. 【数据结构与算法】之深入解析运用链表结构计算“两数相加”的算法实现
  4. LeetCode 多线程 1116. 打印零与奇偶数
  5. 实验1 词法分析程序设计
  6. 深入理解python中的select模块
  7. ASCII码八、十、十六进制对照表
  8. 数据结构和算法 —— 时间复杂度+空间复杂度
  9. PaddlePaddle训练营——公开课——AI核心技术掌握——第1章迈入现代人工智能的大门——多层感知机网络模型
  10. 【机器视觉】 measure_pos算子