天天看點

關鍵字 static_assert

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

其文法很簡單:static_assert(常量表達式,提示字元串)。

如果第一個參數常量表達式的值為真(true或者非零值),那麼static_assert不做任何事情,就像它不存在一樣,否則會産生一條編譯錯誤,錯誤位置就是該static_assert語句所在行,錯誤提示就是第二個參數提示字元串。

說明

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

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

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

由于之前有望加入C++0x标準的concepts提案最終被否決了,是以對于檢查模闆參數是否符合期望的重任,就要靠static_assert來完成了,是以如何構造适當的常量表達式,将是一個值得探讨的話題。

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

範例

下面是一個來自MSDN的簡單範例:

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

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

再看另一個範例:

1: struct MyClass      
2: {      
3:     char m_value;      
4: };      
5:        
6: struct MyEmptyClass      
7: {      
8:     void func();      
9: };      
10:        
11: // 確定MyEmptyClass是一個空類(沒有任何非靜态成員變量,也沒有虛函數)      
12: static_assert(std::is_empty<MyEmptyClass>::value, "empty class needed");      
13:        
14: //確定MyClass是一個非空類      
15: static_assert(!std::is_empty<MyClass>::value, "non-empty class needed");      
16:        
17: template <typename T, typename U, typename V>      
18: class MyTemplate      
19: {      
20:     // 確定模闆參數T是一個非空類      
21:     static_assert(      
22:         !std::is_empty<T>::value,      
23:         "T should be n non-empty class"      
24:         );      
25:        
26:     // 確定模闆參數U是一個空類      
27:     static_assert(      
28:         std::is_empty<U>::value,      
29:         "U should be an empty class"      
30:         );      
31:        
32:     // 確定模闆參數V是從std::allocator<T>直接或間接派生而來,      
33:     // 或者V就是std::allocator<T>      
34:     static_assert(      
35:         std::is_base_of<std::allocator<T>, V>::value,      
36:         "V should inherit from std::allocator<T>"      
37:         );      
38:        
39: };      
40:        
41: // 僅當模闆執行個體化時,MyTemplate裡面的那三個static_assert才會真正被演算,      
42: // 藉此檢查模闆參數是否符合期望      
43: template class MyTemplate<MyClass, MyEmptyClass, std::allocator<MyClass>>;      

通過這個例子我們可以看出來,static_assert可以很靈活的使用,通過構造适當的常量表達式,我們可以檢查很多東西。比如範例中std::is_empty和std::is_base_of都是C++新的标準庫提供的type traits模闆,我們使用這些模闆可以檢查很多類型資訊。

-------------------------------------------------------------------------------------------------------------------------------------------------

                                  以上内容為本人學習摘錄,來源多為網上搜尋所得,如您認為侵犯您的版權,請留言告知,不勝感激。

---------------------