c++11新特性 嚼文嚼字
常量表示式是指值不會改變而且在編譯過程就可以獲得計算結果的表示式。顯然,字面值屬於常量表示式,用常量表示式初始化的 const 物件也是常量表示式。以下:
express
const int max_num = 20; // max_num是常量表示式
const int limit = max_num + 1; // limit 是常量表示式
int staff_size = 2; // staff_size 不是常量表示式,由於staff_size沒有用const修飾
const int zs = get_size(); // sz 不是常量表示式,雖然sz是個常量,但它的值在執行時才能肯定
一. const 和constexpr的區別
(一)修飾變數時,const為「執行期常量」,即執行期資料是唯讀的。而constexpr為「編譯期」常量,這是const沒法保證的。二者都是物件和函式介面的組成部分。程式設計
(二)修飾函式時,與const關鍵字相比,constexpr關鍵字不只能夠修飾變數和指標,還能夠修飾函式(含建構函式)。注意constexpr用於定義自定義類的物件時,要求該類具備常量建構函式,而使用const定義類物件時,則無此要求。函式
(三)二者在修飾指標時,行為有所差別。const放在號前,表示指標指向的內容不能被修改.const放在號後,表示指標不能被修改;而constexpr關鍵字只能放在*號前面,而且表示指標所指的內容不能被修改。spa
2、常量表示式函式指標
(一)構成constexpr函式的條件code
1. 函式體只有單一的return語句(能夠經過「:」或遞迴來擴充套件)。在c++14中這條己經再也不是限制。orm
2. 函式體必須有返回值(c++11中要求不能是void函式,但c++14己再也不限制)物件
三、constexpr函式內部不能呼叫很是量表示式的函式,會形成編譯失敗。blog
4. return返回語句表示式中不能使用很是量表示式的函式、全域性資料,且必須是乙個常量表示式。遞迴
(二)注意事項
1. 在使用常量表示式函式前,必須先被定義。不能先宣告,而後在函式呼叫後再定義。
2. constexpr函式在呼叫時若傳入的實參均為編譯期己知的,則返回編譯期常量。只要任何乙個實參在編譯期未知,則它的運做與普通函式無異,將產生執行期結果。
3. constexpr函式的構成條件不知足時,就會變成乙個普通的函式。同時constexpr函式能夠同時應用於編譯期語境或執行期語境(編譯期語境如constexpr int a = func_constexpr(x, y)。執行期語境如int a = func_constexpr(x, y))。
【程式設計實驗】const和constexpr的差別
#include
#include
using namespace std;
int g_count = 0;
int normalfunc(int x)
//constexpr函式(便可當編譯期常量表示式函式,也能夠看成普通函式使用)
constexpr int func1(int x)
constexpr void func2(){} //普通函式,constexpr必須有非void的返回值型別
constexpr int func3(); //注意這裡只宣告,定義在main()函式以後
//constexpr int func4() //編譯失敗
////冪函式:用於計算base的exp次冪
constexpr int pow(int base, int exp)
return ret;int main()
3、constexpr的應用
(一)定義自定義類的constexpr物件。
1. 自定義類的建構函式須為constexpr函式。
2. constexpr不能用於修飾virtual函式。由於virtual是執行時的行為,與constexpr的意義衝突。
3. c++11中被宣告為constexpr成員函式會自動設為const函式,但c++14中再也不自動設為const函式。
(二)函式模板: 例項化後的函式是否為constexpr函式,在編譯期是不肯定的,取決於傳入的實參是否為constexpr型別。
(三)constexpr型別的函式遞迴
1. 利用constexpr進行編譯期運算的程式設計方式稱為constexpr元程式設計
2 .基於模板編譯期運算的程式設計方式,叫模板元程式設計。
【程式設計實驗】constexpr的應用
#include
using namespace std;
//1. constexpr建構函式和成員函式
class point
//成員函式(注意:constexpr不容許用於修飾virtual函式)
constexpr double getx() const noexcept //constexpr函式,在c++11中預設為const函式。但c++14中取消了,這裡加const
constexpr double gety() const noexcept
//如下兩個函式在c++11中沒法宣告為constexpr(c++14能夠!),緣由以下:
中被宣告為constexpr成員函式會自動設為const函式,而這兩個函式須要更改為員變數的值,這與const成員函式
//卻不容許需改為員的值,會產生編譯錯誤。c++14中constexpr函式再也不預設為const函式,所以能夠修改為員變數。
//2. c++11中constexpr函式不能返回void型,但c++14中再也不限制。
constexpr void setx(double newx) noexcept //c++11中須去掉constexpr;
constexpr void sety(double newy) noexcept
//計算中點座標
constexpr point midpoint(const point& p1, const point& p2) noexcept;}
//返回p相對於原點的中心對稱點(c++14)
constexpr point reflection(const point& p) noexcept
//2. 函式模板:(constexpr元程式設計)
//函式是否為constexpr函式,編譯期未知。取決於傳入的實參t是否為constexpr變數/物件
template
constexpr t func(t t)
struct notliteral
//注意:建構函式不是constexpr型別!
};型別的遞迴函式
求斐波那契數
constexpr int fib(int n)
模板遞迴(模板元程式設計)
template
struct fibonacci
;//特化
template<> struct fibonacci<2> ;
template<> struct fibonacci<1> ;
template<> struct fibonacci<0> ;
void printarray(int a, int len)
; //ok,同上
求中點constexpr auto mid = midpoint(p1, p2); //mid為編譯期常量,mid.getx()也是編譯期常量!!!
求關於原點的對稱點
constexpr auto reflectedmid = reflection(mid);
//2. constexpr型的函式模板
notliteral n1; //非constexpr物件
notliteral n2 = func(n1); //傳入實參為非constexpr物件,func成為普通函式!
//constexpr notliteral n3 = func(n1); //error,因為notliteral的建構函式不是constexpr型別,
//不能用constexpr定義該型別的constexpr的物件!!!
constexpr int a = func(1); //ok,1為constexpr物件
//3. constexpr型別遞迴函式
int fib1;
printarray(fib1, 4);
int fib2 = ;
printarray(fib1, 4);
return 0;
}
/*輸出結果
fibonacci: 89 144 233 377
fibonacci: 89 144 233 377
*/
C 11新特性 auto關鍵字
熟悉指令碼語言的人都知道,很多指令碼語言都引入了 型別自動推斷 技術 比如python,可以直接宣告變數,在執行時進行型別檢查。隨著c 11標準的發布,c 語言也引入了型別自動推斷的功能,這就是我們今天要介紹的auto關鍵字。c 是一種強型別語言,宣告變數時必須明確指出其型別。但是,在實踐中,優勢我...
C 11新特性 auto關鍵字
在c 98標準中就存在著auto關鍵字,c 98標準中auto關鍵字用於自動變數的宣告,但在預設情況下即使不宣告auto,函式內部的變數也是具有自動儲存期的。因此由於使用極少且多餘,在c 11中已刪除這一用法。void fun c 11新標準引入了auto型別說明符,採用它可以讓編譯器幫助我們分析表...
C 11新特性 auto關鍵字
include include using namespace std template void add t t,u u int main templatet,class u auto add t t,u u decltype t u auto a 10 auto pa new auto a au...