C++11 static_assert

來源:互聯網
上載者:User

標籤:namespace   上進   type   string   實現   因此   false   不能   getc   

C++11 static_assert

 

C++0x中引入了static_assert這個關鍵字,用來做編譯期間的斷言,因此叫做靜態斷言。

其文法:static_assert(常量運算式,提示字串)。

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

 

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

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

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

由於之前有望加入C++0x標準的concepts提案最終被否決了,因此對於檢查模板參數是否符合期望的重任,就要靠static_assert來完成了,所以如何構造適當的常量運算式,將是一個值得探討的話題。

效能方面,由於是static_assert編譯期間斷言,不產生目標代碼,因此static_assert不會造成任何運行期效能損失。

 

簡單範例:

static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");

static_assert用來確保編譯僅在32位的平台上進行,不支援64位的平台,該語句可以放在檔案的開頭處,這樣可以儘早檢查,以節省失敗情況下的編譯時間。

另一個範例:

#include <cassert>#include <cstring>using namespace std;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;}

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

使用static_assert替換assert再次編譯,即可獲得一個錯誤並顯示我們指定的錯誤資訊。

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

int positive(const int n) {    static_assert(n > 0, "value must > 0");    return 0;}

 

和Assert,#error比較

我們知道,C++現有的標準中,就有assert、#error兩個設施,也是用來檢查錯誤的,還有一些第三方的靜態斷言實現。

assert是運行期斷言,它用來發現運行期間的錯誤,不能提前到編譯期發現錯誤,也不具有強制性,也談不上改善編譯資訊的可讀性,既然是運行期檢查,對效能當然是有影響的,所以經常在發行版本中,assert都會被關掉;

#error可看做先行編譯期斷言,甚至都算不上斷言,僅僅能在先行編譯時顯示一個錯誤資訊,它能做的不多,可以配合#ifdef/ifndef參與先行編譯的條件檢查,由於它無法獲得編譯資訊,當然就做不了更進一步分析了。

stastic_assert提交到C++0x標準之前,為了彌補assert#error的不足,出現了一些第三方解決方案,可以作編譯期的靜態檢查,例如:BOOST_STATIC_ASSERTLOKI_STATIC_CHECK,但由於它們都是利用了一些編譯器的隱晦特性實現的trick,可移植性、簡便性都不是太好,還會降低編譯速度,而且功能也不夠完善,例如BOOST_STATIC_ASSERT就不能定義錯誤提示文字,而LOKI_STATIC_CHECK則要求提示文字滿足C++類型定義的文法。

 

C++11 static_assert

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.