C++11关键字constexpr看这篇就够了

C++11关键字constexpr看这篇就够了一 在普通函数中的使用例如下面的代码 数组的大小必须是常量 在声明数组 array 时 用函数返回值 此时会报错 errorC2131 表达式的计算结果不是常数 note 对未定义的函数或为未声明为 constexpr 的函数的调用导致了故障用 constexpr 关键字可以解决这种问题 在 GetLen 函数前加 constexpr 声明 代码如下 当然 constexpr 修饰的函数也有一定的限制 函数体尽量只包含一个 return 语句 多个可能会编译出错

一、在普通函数中的使用

例如下面的代码,

C++11关键字constexpr看这篇就够了

数组的大小必须是常量,在声明数组array时,用函数返回值,此时会报错:

error C2131: 表达式的计算结果不是常数

note: 对未定义的函数或为未声明为“constexpr”的函数的调用导致了故障

用constexpr关键字可以解决这种问题,在GetLen函数前加constexpr声明,代码如下:

C++11关键字constexpr看这篇就够了

编译器会将constexpr函数视为内联函数!所以在编译时若能求出其值,则会把函数调用替换成结果值。

二、在类的构造函数中也可以使用constexpr关键字

        代码如下:

#include <iostream> using namespace std; class Test { public: constexpr Test(int num1, int num2) : m_num1(num1), m_num2(num2) { } public: int m_num1; int m_num2; }; int main(void) { constexpr Test t1(1, 2); enum e { x = t1.m_num1, y = t1.m_num2 }; return 0; }

  如果在构造函数中加点代码,就会编译报错,如下:

C++11关键字constexpr看这篇就够了

三、const和constexpr对指针的修饰有什么差别呢?

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

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

       constexpr是一种很强的约束,更好的保证程序的正确定语义不被破坏;编译器可以对constexper代码进行非常大的优化,例如:将用到的constexpr表达式直接替换成结果, 相比宏来说没有额外的开销。

       代码:

#include <iostream> using namespace std; int g_tempA = 4; const int g_conTempA = 4; constexpr int g_conexprTempA = 4; int main(void) { int tempA = 4; const int conTempA = 4; constexpr int conexprTempA = 4; /*1.正常运行,编译通过*/ const int *conptrA = &tempA; const int *conptrB = &conTempA; const int *conptrC = &conexprTempA; /*2.局部变量的地址要运行时才能确认,故不能在编译期决定,编译不过*/ constexpr int *conexprPtrA = &tempA; constexpr int *conexprPtrB = &conTempA; constexpr int *conexprPtrC = &conexprTempA; /*3.第一个通过,后面两个不过,因为constexpr int *所限定的是指针是常量,故不能将常量的地址赋给顶层const*/ constexpr int *conexprPtrD = &g_tempA; constexpr int *conexprPtrE = &g_conTempA; constexpr int *conexprPtrF = &g_conexprTempA; /*4.局部变量的地址要运行时才能确认,故不能在编译期决定,编译不过*/ constexpr const int *conexprConPtrA = &tempA; constexpr const int *conexprConPtrB = &conTempA; constexpr const int *conexprConPtrC = &conexprTempA; /*5.正常运行,编译通过*/ constexpr const int *conexprConPtrD = &g_tempA; constexpr const int *conexprConPtrE = &g_conTempA; constexpr const int *conexprConPtrF = &g_conexprTempA; return 0; }

四、对引用的修饰

  代码如下:

#include <iostream> using namespace std; int g_tempA = 4; const int g_conTempA = 4; constexpr int g_conexprTempA = 4; int main(void) { int tempA = 4; const int conTempA = 4; constexpr int conexprTempA = 4; /*1.正常运行,编译通过*/ const int &conptrA = tempA; const int &conptrB = conTempA; const int &conptrC = conexprTempA; /*2.有两个问题:一是引用到局部变量,不能再编译器确定;二是conexprPtrB和conexprPtrC应该为constexpr const类型,编译不过*/ constexpr int &conexprPtrA = tempA; constexpr int &conexprPtrB = conTempA; constexpr int &conexprPtrC = conexprTempA; /*3.第一个编译通过,后两个不通过,原因是因为conexprPtrE和conexprPtrF应该为constexpr const类型*/ constexpr int &conexprPtrD = g_tempA; constexpr int &conexprPtrE = g_conTempA; constexpr int &conexprPtrF = g_conexprTempA; /*4.正常运行,编译通过*/ constexpr const int &conexprConPtrD = g_tempA; constexpr const int &conexprConPtrE = g_conTempA; constexpr const int &conexprConPtrF = g_conexprTempA; return 0; }

       简单的说constexpr所引用的对象必须在编译期就决定地址。还有一个奇葩的地方就是可以通过上例conexprPtrD来修改g_tempA的值,也就是说constexpr修饰的引用不是常量,如果要确保其实常量引用需要constexpr const来修饰。

       以上是C++ 11 constexpr的简单应用,要深入学好C++,需要长期的训练,刻意练习。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233215.html原文链接:https://javaforall.net

(0)
上一篇 2025年8月6日 下午6:01
下一篇 2025年8月6日 下午6:22


相关推荐

  • pycharm整理代码格式的快捷键

    pycharm整理代码格式的快捷键pycharm 整理代码格式的快捷键人狠话不多给好评点赞就行快捷键 Ctrl Alt L 可以将代码格式工整化非常漂亮舒服如果键盘失灵 哈哈哈哈哈极端情况 也可以用鼠标 Code gt ReformatCode 另 eclipse 里面的类似快捷键 Ctrl shift F 嘿嘿嘿

    2026年3月27日
    3
  • 驼峰命名法

    驼峰命名法驼峰命名法驼峰命名法是一种命名规范 广泛用于各种计算机开发场景中 帮助开发人员清晰的命名各个文件 1 分类大驼峰命名法小驼峰命名法 2 使用这种命名法长得很像骆驼的驼峰 因此叫做驼峰命名法 驼峰命名法指的是将文件名通过英文命名 除了第一个单词以外 其他单词的第一个首字母都为大写状态 intnameArray 小驼峰命名法 intNameArray 大驼峰命名法大驼峰和小驼峰的区别在于 第一个单词的首字母是否大写 如果大写 则为大驼峰命名 反之 为小驼峰 3 注意

    2026年3月26日
    2
  • 关于hashlib哈希算法的一些个人笔记

    关于hashlib哈希算法的一些个人笔记摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。hashlib提供了常见的摘要算法,具体包括md5、sha1、sha224、sha256、sha512等,我们一般用的比较多是md5。注意加密是单向的。通过hashlib,可以把任意长度的字符串转换成固定长度的加密串,通常我们一般用hexdigest(),也就是…

    2022年6月3日
    46
  • Tidb查配置和添加配置

    Tidb查配置和添加配置

    2021年5月14日
    103
  • ubuntu镜像下载教程_Ubuntu镜像

    ubuntu镜像下载教程_Ubuntu镜像在众多的linux操作系统中,Ubuntu(乌班图)是目前主流的linux操作系统。而绝大部分新手网友要接触linux或使用linux操作系统,当然是首选Ubuntu(乌班图)linux操作系统。因为Ubuntu系统绝大部分是图形化操作,很少会使用到命令,同时在linux操作系统中支持Ubuntu系统的软件、游戏也最多。Ubuntu官方网站:http://www.ubuntu.com/downl

    2025年6月26日
    7
  • 第一章附加:线程锁synchronized方法,synchronized块和synchronied(this)总结[通俗易懂]

    第一章附加:线程锁synchronized方法,synchronized块和synchronied(this)总结[通俗易懂]第一章附加:线程锁synchronized方法,synchronized块和synchronied(this)总结

    2022年4月23日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号