惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
爱范儿
爱范儿
罗磊的独立博客
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
U
Unit 42
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
H
Help Net Security
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理

博客园 - 新西兰程序员

C++ 构造函数中的初始化参数列表initializer list C++中的线程thread,以及C++11中的std::atomic学习 Leetcode56 Merge Intervals 合并区间 -- C++实现 C++中的内存对齐 C++中的static关键字使用以及全局变量 C++17中的结构化绑定Structured Binding C++中的函数参数是指针类型, 是按值传递 C++中异常处理机制中的栈展开stack unwinding C++实现链表反转 Linux中的性能分析工具 perf 来分析C++性能 C++17中新建一个类时,编译器默认生成的类成员函数 QT中的元对象系统 Leetcode 114 - 二叉树展开为链表 Leetcode65 有效数字 - 判断给定的字符串是否是一个有效数字 LettCode2289-Steps to Make Array Non-descreasing C#中的委托详解 C++中的std::function C++中的仿函数Functor C++中的左值和右值,以及右值引用,移动语义 C++中传递参数是指针类型以及传入参数是指针的指针(**)详解 C++中GetTickCount函数学习 C++中以类的成员函数作为Windows callback函数需要设置成static函数 C#中的System.Security.SecureString学习 C++中的悬挂指针和野指针 C++中四种不同的对象生存方式(in stack, in heap, global, local static) C#中使用Parallel类来进行多线程并发编程 String类型转LPCTSTR -----理解C++中的字符串类型转换 C++中的虚函数和虚函数表 C++中基类指针指向派生类对象 数据结构 - 栈的学习
C++中的const和constexpr异同比较
新西兰程序员 · 2024-10-23 · via 博客园 - 新西兰程序员

constexpr是C++11引入的关键字,这个关键字用于指明其后面是一个常量,编译器在编译程序时会将其结果计算出来,而无需等到程序运行阶段,这样的优化极大的提高了程序的运行效率

我们知道,C++程序的执行过程,大概需要经历  编译,链接,运行这3个阶段.  这里值得特别关注的是,常量表达式和非常量表达式的计算时机并不同 => 非常量表达式只有在程序运行阶段时才会计算出结果, 而常量表达式的计算往往发生在程序的编译阶段, 这可以极大的提高程序的执行效率 => 因为表达式只需要在编译阶段计算一次,节省了每次运行时都需要计算一次的时间和资源消耗.

关键字constexpr表示的就是常量表达式.  在实际开发工作中,我们经常会用到常量表达式,比如数组的长度,就必须是一个常量表达式

int testArr1[3] = {0,1,2};  //ok
int testArr2[2 * 5] = {0}; //ok
int len = 10;
int testArr3[len] = {0}; //错误,因为len是一个整形变量,并不是常量表达式

 2. constexpr还可以用来修饰函数的返回值  => 这样的函数称为 “常量表达式函数”   => 这样的常量表达式函数必须满足3个条件

   条件1:  函数必须有返回值,并且返回值不能是void

   条件2: 整个函数的函数体中,除了可以包含using指令,typedef语句以及static_assert断言外, 就只能包含一条return返回语句,并且return返回的表达式必须是常量表达式

               eg:      

constexpr int fun(int x)
{
    return 1 + 2 + x;
}

    条件3: constexpr修饰的常量表达式函数在使用之前(在调用它的位置之前),必须由对应的函数定义.  普通函数的调用只需要提前写好该函数的声明部分即可,函数的定义部分可以放在调用位置之后甚至其他文件中,但常量表达式函数在使用前,必须有该函数的定义

#include <iostream>
using namespace std;

constexpr int func(int x);

int main()
{
    int arr[func(2)] = {0};  //这里会报错,因为这里调用constexpr常量表达式函数func时,它只是在上面声明了,但是还没有定义。 ta的定义在main()函数后面,这是不行的
    return 0;
}

constexpr int fun(int x)  
{
     return 1 + 2 + x;
}

3. constexpr修饰类的构造函数

    constexpr还可以用来修饰类的构造函数,这样做的目的是为了得到一个常量对象。 constexpr修饰的构造函数称为常量构造函数,常量构造函数有一个要求 => 构造函数的函数体必须为空,并且必须采用初始化列表的方式为各个成员赋值

#include <iostream>
using namespace std;

struct Person
{
const char* _name;
int _age;

constexpr Person(const char* name, int age) : _name(name), _age(age)
{}
}

int main()
{
constexpr Person p{"武田",55};
cout << p._name << " " << p._age <<end1; // 武田 55
return 0;
}