15 | constexpr:一个常态的世界
该思维导图由 AI 生成,仅供参考
初识 constexpr
- 深入了解
- 翻译
- 解释
- 总结
C++11引入了`constexpr`关键字,C++14对其进行了大幅改进,使得编译期编程变得更加简单。`constexpr`关键字用于定义编译时完全确定的常量和函数,允许进行编译期计算。通过`constexpr`函数,可以在编译期间产生编译期常数,从而实现编译期计算。与`const`的区别在于,`constexpr`表示编译期常数,而`const`表示运行时常量。C++17引入了内联变量的概念,允许在头文件中定义内联变量,解决了类的静态常量需要有一个定义的问题。此外,C++14引入了变量模板的概念,允许更简洁地表达类型相关的编译期常量。需要注意的是,`constexpr`变量仍然是const常类型。总之,`constexpr`关键字为C++编程带来了更多的编译期计算能力,使得编译期编程变得更加简单和灵活。文章还介绍了`if constexpr`的使用,以及`output_container.h`中的C++语法特性,展示了编译期常量表达式和编译期条件语句的应用,以及容器输出函数的实现。这些新特性对编译期编程有了很大的改进,可以让代码变得更直观。
《现代 C++ 编程实战》,新⼈⾸单¥59
全部留言(21)
- 最新
- 精选
- 李亮亮我觉得我学习这个专栏只是为了能看懂这些新特性,写是写不出来,规则太多太复杂了。
作者回复: 很少需要自己写的。就像学了微积分大部分人也没机会用一样😂。但一点都看不懂也是会很有问题的。
2019-12-3011 - czh老师好,有个小疑问,文中提到: “上一讲的结尾,我们给出了一个在类型参数 C 没有 reserve 成员函数时不能编译的代码:” 这里提到使用 if constexpr,可以解决上述问题。这里没有过多的解释,我理解是:使用if constexpr之后,如果没有reserve成员,那就会在编译期跳过这个if中的内容,因此不会检查container.reserve()。 不知道理解是否正确?
作者回复: 对。一般的 if 是运行期条件语句;if constexpr 是编译期条件语句。
2020-02-0429 - geek试着回答一下两个思考问题: 1 我认为不用consexpr,就要用enable_if,类似于上一节的append方法那样,在有两种可能情况时,要写两个方法,做标签分发。这种方式的一个推广就是:有多少种可能,就要写多少个对应的分发方法。 2 不用constexpr的缺点,就是代码冗余而且不易读。那么用constexpr的优点就是代码无冗余,易读。
作者回复: 嗯。再补充一个,如果你有n个不同的静态条件,你需要分发的函数数量是 2^n。🤓
2021-03-0822 - Jerry Tan您好老师, 请问想学C++ 您有什么比较好的推荐的开发工具吗 谢谢
作者回复: 第 21 讲会讨论一点工具。不过你指的是什么工具呢?……如果你用 Windows,就从 Visual Studio 的免费 Community 版开始吧。
2019-12-3052 - Slience-0°C常量区分编译期?和运行期?
作者回复: 对,这是很重要的一个概念。能编译期确定的东西才能做编译期计算。
2022-02-181 - Slience-0°C老师好,现代C++如何优雅的定义字符串常量?直接使用const std::string var = "xxxx "有些静态代码检查工具会提示可能会抛出无法捕获的异常!
作者回复: 像你这种用法可以考虑用 std::string_view。 可参考我这个知乎回答: https://www.zhihu.com/question/483774144/answer/2251359893
2022-02-181 - 心态正常吴老师,您好,有个问题想请教一下,文章开头的两个示例我在centos8上使用g++ 8.3.1的编译器编译通过了,因为没有用到constexpr的特性,预期在int a[n]这一行会报错,但是实际上并没有给出错误,这是编译器做了优化处理吗?
作者回复: 是可以过的。只有第三个例子,模板参数,才会要求特别严。 不是考大家知道哪些行哪些不行。正如下面写的:“这些问题的答案不直观。”
2021-04-261 - 清水吴老师,你好,请教个问题 constexpr int factorial(int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } } 如果constexpr 修饰函数 这样是编译不过的,提示not a return-statement (至少c++11不行) 没有尝试过是否其他编译器 多行编译 通过 如果修改为一行表达式是没问题的,那么这是constexpr关键字 用法要求还是其他原因导致?
作者回复: 编译器太老,升级到至少支持C++14的编译器,比如GCC 7。 GCC 6也许也可以,但我没有环境。毕竟,现在GCC已经发布10.2了。这门课程期望你用GCC 7以上的编译器。
2021-01-141 - talor您好, constexpr int a = 42; constexpr const int& b = a; 这个例子编译不过,编译器是gcc 10.2.1
作者回复: 我大概知道你的问题了。这两句是不能放在函数体里的。constexpr 引用只能绑定到全局变量上。
2020-08-301 - g_boshu吴老师您好,我对以下代码有点儿疑惑: // Type trait to detect std::pair template <typename T> struct is_pair : std::false_type {}; template <typename T, typename U> struct is_pair<std::pair<T, U>> : std::true_type {}; template <typename T> inline constexpr bool is_pair_v = is_pair<T>::value; template <typename T, typename U> struct is_pair<std::pair<T, U>>: std::true_type {}; 看着应该是一个偏特化,模板的参数却变多了,一般偏特化不应该是参数变少吗?谢谢
作者回复: 是偏特化。没有规定说偏特化一定参数更少啊。
2020-04-011