天天看點

C++11 static_assert關鍵字

文章目錄

  • static_assert簡介
  • static_assert文法:
  • 參數描述:
  • static_assert作用:
  • 注意事項
  • 代碼案例
  • 檢查模闆參數示例

我們知道,C++現有的标準中就有assert、#error兩個方法是用來檢查錯誤的,除此而外還有一些第三方的靜态斷言實作。

​assert​

​是運作期斷言,它用來發現運作期間的錯誤,不能提前到編譯期發現錯誤,也不具有強制性,也談不上改善編譯資訊的可讀性。

既然是運作期檢查,對性能肯定是有影響的,是以經常在發行版本中,assert都會被關掉。

​#error​

​可看作是預編譯期斷言(甚至都算不上斷言),僅僅能在預編譯時顯示一個錯誤資訊,可以配合#ifdef/ifndef參與預編譯的條件檢查。

由于它無法獲得編譯資訊,當然,也就做不了更進一步分析了。

在stastic_assert送出到C++0x标準之前,為了彌補assert和#error的不足,出現了一些第三方解決方案,可以作編譯期的靜态檢查:

​static_assert​

​關鍵字,用來做編譯期間的斷言,是以叫做靜态斷言。

static_assert(常量表達式,提示字元串)。
      

  • 如果第一個參數常量表達式的值為false,會産生一條編譯錯誤,錯誤位置就是該static_assert語句所在行
  • 第二個參數就是錯誤提示字元串。

使用static_assert,我們可以在編譯期間發現更多的錯誤,用編譯器來強制保證一些契約,并幫助我們改善編譯資訊的可讀性,尤其是用于模闆的時候。

static_assert可以用在全局作用域中,命名空間中,類作用域中,函數作用域中,幾乎可以不受限制的使用。

編譯器在遇到一個static_assert語句時,通常立刻将其第一個參數作為常量表達式進行演算,但如果該常量表達式依賴于某些模闆參數,則延遲到模闆執行個體化時再進行演算,這就讓檢查模闆參數成為了可能。

由于是static_assert編譯期間斷言,不生成目标代碼,是以static_assert不會造成任何運作期性能損失。

注意:static_assert的斷言表達式的結果必須是在編譯時期可以計算的表達式,即必須是常量表達式。如果使用變量,則會導緻錯誤。

int positive(const int n) {
static_assert(n > 0, "value must > 0");
return 0;
}
      
C++11 static_assert關鍵字

這裡使用assert運作時斷言,但如果bit_copy不被調用,我們将無法觸發該斷言,實際上正确産生斷言的時機應該在模版執行個體化時,即編譯時期。

C++11 static_assert關鍵字
C++11 static_assert關鍵字
#include <stdio.h>
#include <cassert>
#include <cstring>

template <typename T, typename U> int bit_copy(T& a, U& b){
assert(sizeof(b) == sizeof(a));  //static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!");
memcpy(&a,&b,sizeof(b));
};

int main()
{
int aaa = 0x2468;
double bbb;
bit_copy(aaa, bbb);

getchar();
return 0;
}