【C++ Primer 第六章】 constexpr函数

constexpr函数

constexpr函数: constexpr函数是指用于常量表达式的函数,函数的返回值类型以及所有的形参类型必须是字面值,而且函数必须有且只有一条return语句。

 1 [tect2.cpp]
 2 #include <iostream>
 3 using namespace stdl;
 4
 5 constexpr int screen(int x)               // constexpr
 6 {
 7    return x;
 8 }
 9
10 int main()
11 {
12     const int x = 0;                     // const,是常量表达式,因为值不会发生改变
13     constexpr int z =  screen(x);        // constexpr
14     cout << z<<endl;
15     return 0;
16 }
 1 [tect2.cpp]
 2
 3 #include <iostream>
 4 using namespace std;
 5
 6 constexpr int screen(int x)
 7 {
 8    return x;
 9 }
10
11
12 int main()
13 {
14     int x = 0;                // 不是常量表达式,因为值会改变
15     int z =  screen(x);
16     cout << z<<endl;
17     return 0;
18 }

分析 首先说明一下常量表达式的定义:常量表达式是指值不会改变且在编译阶段就可以得到结果的表达式。 
(1)[test1.cpp] 符合constexpr函数的常规用法,即函数的返回类型以及所有的形参类型必须是字面值类型(字面值类型即编译过程就能得到结果的类型)。此时,如果将 const int x = 0; 变为 int x = 0;就会报错,因为screen函数的用在一个需要常量表达式的上下文中(constexpr类型的变量必须用常量表达式初始化),编译器在编译的过程中会检查函数的返回值是不是常量表达式,如果不是就会报错。 
(2)[test2.cpp] 表示constexpr函数可以返回非常量表达式,编译的过程没有报错,原因是screen函数并没有用在一个需要常量表达式的上下文中,编译器正在编译的过程中不会去检查该函数的返回值,也就不会报错。
(3)作为补充,需要注意的是constexpr函数必须有return语句。

结论:可以这样认为:C++不要求constexpr函数必须返回常量表达式(以问题中的screen constexpr函数为例)

• 如果在不需要常量表达式的上下文,如: int z = screen(x); 可以不返回常量表达式,此时编译器不会检查函数的结果是否会返回常量表达式。
• 如果是在需要常量表达式的上下文中,如: constexpr int z = screen(x); 那么,constexpr函数必须可以返回常量表达式。此时编译器会去检查函数返回的结果是不是常量表达式,如果不是,就会报错。

参考资料

[1] SegmentFault,关于constexpr函数的一个问题

原文地址:https://www.cnblogs.com/sunbines/p/8907386.html

时间: 2024-11-07 11:35:19

【C++ Primer 第六章】 constexpr函数的相关文章

C++ Primer【第五版】习题参考答案——第六章(函数)

本系列文章会不断更新,但是时间不能保证.另外基本上都是自己做的答案,仅供参考,如果有疑问欢迎交流. #include <iostream> #include <initializer_list> using namespace std; int test_Ex_6_27(std::initializer_list<int> li); int main() { cout << test_Ex_6_27({23,78,89,76,90}) << en

c++ primer(第五版)学习笔记及习题答案代码版(第六章)函数

笔记较为零散,都是自己不熟悉的知识点. 习题答案至于一个.cc 中,编译需要包含Chapter6.h头文件. 需要演示某一题直接修改 #define NUM***, 如运行6.23题为#define NUM623: chapter 6 1. 形参初始化的机理与变量初始化一样. 当形参是引用类型时,它对应的实参被引用传递或者函数被传引用调用. 2. const和实参 void fcn(const int i){ /*fcn能够读取i,但是不能向i写值*/} void fcn(int i){ /*.

第六章:函数

一.参数传递 1.形参为引用类型时,将绑定到相应的实参上,否则为实参的拷贝:在C++中建议用引用类型代替指针 2.const 形参: 对于顶层的const,在函数形参中无效,也不能构成重载函数 形参中尽量使用常量引用,对于普通引用会有误导,主要是非常量引用会导致函数不能接受常量的类型 3.数组形参:传递给函数的值为数组的首元素指针,所以一开始不知道数组的大小,有三种解决方法 如果是C风格的字符串,则要保证字符串中最后一个字符为空字符 传递数组的首元素好尾后元素的指针,使用begin和end函数

《Python基础教程》 读书笔记 第六章 抽象 函数 参数

6.1创建函数 函数是可以调用(可能包含参数,也就是放在圆括号中的值),它执行某种行为并且返回一个值.一般来说,内建的callable函数可以用来判断函数是否可调用: >>> x=1 >>> y=math.sqrt >>> callable(x) False >>> callable(y) True 定义函数用def 语句: def fib(num): result=[0,1] for i in range(num-2): resul

C++ primer 第六章笔记

Chapter 6 函数 #函数基础 声明:返回类型.函数名.形参列表.分号 定义:返回类型.函数名.形参列表.函数体 调用:函数或函数指针,实参列表 #参数传递 1.形参是引用类型,它将绑定到对应的实参上.  否则,将实参的值拷贝后赋给形参; 2.C++,建议使用引用类型的形参代替指针; //传引用参数 void reset(int &i){ i = 0; } int j = 24; reset(j); cout << j << endl; //输出是0; 3.使用引用,

C primer 第六章循环 习题6.7

6.07 让用户输入一个单词,并倒序打印这个单词 #include <stdio.h>#include <string.h>int main(void){   char word[20];   size_t size;   int index; printf("Please enter a word:");   scanf("%s",word);   size=(strlen (word));   index=size--; for(;ind

C primer 第六章习题6.13

//编写程序包含8个元素的int类型数组,用for循环设置数组元素,用do while循环显示元素值. #include <stdio.h>int main(void){       int num[8],index,i,pow; for (index=0,i=0,pow=1;index<=7;index++){                pow*=2;                num[index]=pow;            do    {            i++;

c++ primer 5th 笔记:第六章

第六章 笔记 1. 通过调用运算符(call operator)来执行函数.调用运算符的形式是一对圆括号,它作用于一个表达式,该表达式是一个函数或指向函数的指针. 2. 在c++语言中,名字有作用域,对象有生命周期. a. 名字的作用域是程序文本的一部分,名字在其中可见. b. 对象的生命周期是程序执行过程中该对象存在的一段时间. 3. 函数体是一个语句块,块构成一个新的作用域. 4. 形参和函数体内部定义的变量统称为局部变量(local variable). 5. 局部静态对象(local s

C Primer Plus (第五版) 第十六章 C预处理器和C库 编程练习

第十六章 C预处理器和C库 开发一个包含您需要使用的预处理器定义的头文件 //max.h  #ifndef _MAX_H_     #define _MAX_H_     #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #endif 2.两个数的调和平均数可用如下方法得到:首先对两数的倒数取平均值,最后再取倒数.使用#define指令定义一个宏"函数"执行这个运算.编写一个简单的程序测试该宏. #include <stdio.h> #defin