1. 程式人生 > 其它 >C++11 constexpr 變數 和 constexpr 函式

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

學海無涯。

本文來自部落格園,作者:拾荒荒,轉載請註明原文連結:https://www.cnblogs.com/lvvou/p/15684309.html