文章目錄
- 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;
}
這裡使用assert運作時斷言,但如果bit_copy不被調用,我們将無法觸發該斷言,實際上正确産生斷言的時機應該在模版執行個體化時,即編譯時期。
#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;
}