程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ constexpr類型說明符分析

C++ constexpr類型說明符分析

編輯:關於C++

  


關鍵字 constexpr 於 C++11 中引入並於 C++14 中得到改善。它表示常數表達式。與 const 相同,它可應用於變量,因此如果任何代碼試圖修改該值,均將引發編譯器錯誤。與 const 不同,constexpr 也可應用於函數和類構造函數。 constexpr 指示值或返回值是常數,並且如果可能,將在編譯時計算值或返回值。

1 constexpr 變量

constconstexpr 變量之間的主要區別在於:const 變量的初始化可以延遲到運行時,而 constexpr 變量必須在編譯時進行初始化。所有 constexpr 變量均為常量,因此必須使用常量表達式初始化。

constexpr float x = 42.0;
constexpr float y{108};
constexpr float z = exp(5, 3);
constexpr int i; // Error! Not initialized
int j = 0;
constexpr int k = j + 1; //Error! j not a constant expression

一般來說,如果你認定變量是一個常量表達式,那就把它聲明成為constexpr類型。

2 constexpr 函數

constexpr 函數是在使用需要它的代碼時,可以在編譯時計算其返回值的函數。當其參數為 constexpr 值並且在編譯時使用代碼需要返回值時(例如,初始化一個 constexpr 變量或提供一個非類型模板參數),它會生成編譯時常量。使用非constexpr 參數調用時,或編譯時不需要其值時,它將與正則函數一樣,在運行時生成一個值。

#include 

using namespace std;

// Pass by value 
constexpr float exp(float x, int n)
{
    return n == 0 ? 1 :
        n % 2 == 0 ? exp(x * x, n / 2) :
        exp(x * x, (n - 1) / 2) * x;
};

// Pass by reference
constexpr float exp2(const float& x, const int& n)
{
    return n == 0 ? 1 :
        n % 2 == 0 ? exp2(x * x, n / 2) :
        exp2(x * x, (n - 1) / 2) * x;
};

// Compile time computation of array length
template
constexpr int length(const T(&ary)[N])
{
    return N;
}

// Recursive constexpr function
constexpr int fac(int n)
{
    return n == 1 ? 1 : n*fac(n - 1);
}

// User-defined type
class Foo
{
public:
    constexpr explicit Foo(int i) : _i(i) {}
    constexpr int GetValue()
    {
        return _i;
    }
private:
    int _i;
};

int main()
{
    // foo is const:
    constexpr Foo foo(5);
    // foo = Foo(6); // Error!

    //Compile time:
    constexpr float x = exp(5, 3);
    // const float a = 2.0;
    // const int  b  = 2;
    // constexpr float xx = exp2(a, b); // Error!
    constexpr float xx = exp2(2.0, 2);
    constexpr float y{ exp(2, 5) };
    constexpr int val = foo.GetValue();
    constexpr int f5 = fac(5);
    const int nums[]{ 1, 2, 3, 4 };
    const int nums2[length(nums) * 2]{ 1, 2, 3, 4, 5, 6, 7, 8 };

    cout << "The value of foo is " << foo.GetValue() << endl;

}

3 constexpr和指針

還記得const與指針的規則嗎?如果關鍵字const出現在星號左邊,表示被指物是常量;如果出現在星號右邊,表示指針本身是常量;如果出現在星號兩邊,表示被指物和指針兩者都是常量。

const不同,在constexpr聲明中如果定義了一個指針,限定符constexpr僅對指針有效,與指針所指對象無關

const int *p     = 0; // non-const pointer, const data
constexpr int *q = 0; // const pointer, non-const data

與其它常量指針類似,const指針既可以指向常量也可以指向一個非常量:

int j = 0;
constexpr int i = 2;
constexpr const int *p = &i; // const pointer, const data
constexpr int *p1 = &j; // const pointer, non-const data
   
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved