C++11 constexpr 变量 和 constexpr 函数

1.constexpr 变量

首先先了解一个概念:常量表达式。
常量表达式:是值不会改变并且在编译过程就能得到计算结果的表达式。
所以,换个角度想,字面值是属于常量表达式的。
那什么是字面值呢?
很简单,比如1,2,3,4, "123",'1', nullptr等等。
所以,一个对象或者表达式是不是常量表达式是由它的数据类型和初始值共同决定的,
例如:

const int A = 20;     // A 是常量表达式
const int B = A + 1;  // B 是常量表达式
int C = 27;           // C 不是常量表达式,因为非 const
const int D = size(); // D 不是常量表达式,因为不是在编译期间获取到结果

在实际使用中,我想定义一个常量表达式,例如上边例子的 A 一样,但实际中,我们可能会像声明 D 一样的做法,当项目很复杂的时候,我们就分辨不出来一个初始值到底是不是我们认定的常量表达式,当然也有保险的方法,就是声明一个 const 变量来作为初始化,设定为我们认定的常量表达式,但这情况显得麻烦且不严谨了。

为此,C++11 新规定: 允许变量声明为 constexpr 类型,方便编译器来验证变量值是否为一个常量表达式。
例如:

constexpr int A = 10;
constexpr int B = A + 1;

constexpr 和 指针

如果 constexpr 定义了一个指针,限定符 constexpr 仅仅对指针有效,而与所指向的对象无关!
如果 constexpr 定义了一个指针,限定符 constexpr 仅仅对指针有效,而与所指向的对象无关!
如果 constexpr 定义了一个指针,限定符 constexpr 仅仅对指针有效,而与所指向的对象无关!
例如:

#include <iostream>

int value1 = 10; // 测试值1
int value2 = 20; // 测试值2
int value3 = 30; // 测试值3

// 主函数
int main()
{
	const int *ptr1     = &value1; // ptr1 是一个指向整型常量的指针
	constexpr int *ptr2 = &value2; // ptr2 是一个指向整型的常量指针

	*ptr1 = value3;  // 错误,不可改变 *ptr1 的值
	ptr1 = &value3;  // 正确,可改变 ptr1 的指向

	*ptr2 = value3;  // 正确, 可改变 *ptr2 的值 
	ptr2 = &value3;  // 错误,不可改变 ptr2 的指向

	return 0;
}

以上,类似的,我们也可以 constexpr 定义为

constexpr int *A = nullptr; // A 是一个指向整型的常量指针,它的值为空

2.constexpr 函数

constexpr 函数: 是指能用于常量表达式的函数。
例如上边所指声明的 D 变量。
constexpr 函数个规定:
1.函数的返回值和形参类型都是字面值类型
2.函数体内尽量不要包含其他语句,但也可以包含,只是这些语句对运行时不执行操作即可
3.constexpr 函数不一定返回常量表达式
4.一般情况下constexpr 函数都是定义在头文件中

例如:

#include <iostream>

// 测试函数1
const int Fun1(int a) 
{
	return a;
}

// 测试函数2
constexpr int Fun2(int a)
{
	return a;
}

// 主函数
int main()
{
	int i = 2;

	int A1[Fun1(3)]; // 错误,Fun1 不是常量表达式
	int B1[Fun1(i)]; // 错误,Fun1 不是常量表达式

	int A2[Fun2(3)]; // 正确,Fun2 是常量表达式
	int B2[Fun2(i)]; // 错误,Fun2 不是常量表达式

	return 0;
}

3._End

学海无涯。

posted @ 2021-12-13 17:18  想想就很离谱  阅读(131)  评论(0编辑  收藏  举报