现代C++实战30讲
吴咏炜
前 Intel 资深软件架构师
立即订阅
3755 人已学习
课程目录
已更新 18 讲 / 共 30 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | C++这么难,为什么我们还要用C++?
免费
课前必读 | 有关术语发音及环境要求
基础篇 (9讲)
01 | 堆、栈、RAII:C++里该如何管理资源?
02 | 自己动手,实现C++的智能指针
03 | 右值和移动究竟解决了什么问题?
04 | 容器汇编 I:比较简单的若干容器
05 | 容器汇编 II:需要函数对象的容器
06 | 异常:用还是不用,这是个问题
07 | 迭代器和好用的新for循环
08 | 易用性改进 I:自动类型推断和初始化
09 | 易用性改进 II:字面量、静态断言和成员函数说明符
提高篇 (7讲)
10 | 到底应不应该返回对象?
11 | Unicode:进入多文字支持的世界
12 | 编译期多态:泛型编程和模板入门
13 | 编译期能做些什么?一个完整的计算世界
14 | SFINAE:不是错误的替换失败是怎么回事?
15 | constexpr:一个常态的世界
16 | 函数对象和lambda:进入函数式编程
现代C++实战30讲
登录|注册

15 | constexpr:一个常态的世界

吴咏炜 2019-12-30
你好,我是吴咏炜。
我们已经连续讲了几讲比较累人的编译期编程了。今天我们还是继续这个话题,但是,相信今天学完之后,你会感觉比之前几讲要轻松很多。C++ 语言里的很多改进,让我们做编译期编程也变得越来越简单了。

初识 constexpr

我们先来看一些例子:
int sqr(int n)
{
return n * n;
}
int main()
{
int a[sqr(3)];
}
想一想,这个代码合法吗?
看过之后,再想想这个代码如何?
int sqr(int n)
{
return n * n;
}
int main()
{
const int n = sqr(3);
int a[sqr(3)];
}
还有这个?
#include <array>
int sqr(int n)
{
return n * n;
}
int main()
{
std::array<int, sqr(3)> a;
}
此外,我们前面模板元编程里的那些类里的 static const int 什么的,你认为它们能用在上面的几种情况下吗?
如果以上问题你都知道正确的答案,那恭喜你,你对 C++ 的理解已经到了一个不错的层次了。但问题依然在那里:这些问题的答案不直观。并且,我们需要一个比模板元编程更方便的进行编译期计算的方法。
在 C++11 引入、在 C++14 得到大幅改进的 constexpr 关键字就是为了解决这些问题而诞生的。它的字面意思是 constant expression,常量表达式。存在两类 constexpr 对象:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《现代C++实战30讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(4)

  • jerry.tan
    您好老师, 请问想学C++ 您有什么比较好的推荐的开发工具吗 谢谢

    作者回复: 第 21 讲会讨论一点工具。不过你指的是什么工具呢?……如果你用 Windows,就从 Visual Studio 的免费 Community 版开始吧。

    2019-12-30
    3
    2
  • tt
    文中一开始用constexpr
    改造的例子,之所以可以,一定是在使用constexpr的地方“就地”调用了赋值运算符右侧的函数,这样才能得到一个编译期的常量,所以,“内联”是constexpr的应有之意。但是在类外,必须加上inline才可以。

    const本质是一个运行时常量,constexpr才是编译期常数,除了内联展开这个含义,再根据文中ODR的表述,说明constexpr变量是切实分配了内存空间的,是一个左值对象。综合上面的考虑,constexpr意味着被声明的对象是存放在数据段里面的。


    constexpr 变量模板表达一个和某个类型相关的编译期常量,让变量也可以是模板,这句话在本课中,我觉得理解成“把模板对象用一个变量命名”更合适,即把所有符号都绑定到了一个实体上,这样if constexpr才变得可行。解决了上一讲中说的c++中不能像Python一样写代码的问题。

    作者回复: 作为编译期常数,没理由认为一个 constexpr 变量一定会在数据段里的,尤其是优化编译的情况。一般而言,只有非优化编译、又有 ODR-use 才能在 data 段里找到其定义。

    2019-12-30
  • 李亮亮
    我觉得我学习这个专栏只是为了能看懂这些新特性,写是写不出来,规则太多太复杂了。

    作者回复: 很少需要自己写的。就像学了微积分大部分人也没机会用一样😂。但一点都看不懂也是会很有问题的。

    2019-12-30
  • hello world
    如果没有consrexpr条件语句那输出函数就应该写两个吧,也是用sfinae,用那种enable_if形式,true or false

    作者回复: 是,然后要么会有重复的代码,要么得再封装函数来复用。

    2019-12-30
收起评论
4
返回
顶部