static_assert
static_assert 基本上是用來讓編譯器在編譯階段產生錯誤,並輸出給定的錯誤訊息的 declaration;他可以判斷給定的 constant expression,在不符合條件的情況下,就讓編譯器編譯失敗,產生錯誤訊息。他的形式很簡單,就是:
static_assert( constant-expression, string-literal );
static_assert 在 constant-expression 為 true(或非 0)的時候,完全不會有任何反應,但是如果是 false(或 0)的時候,就會讓編譯器編譯失敗,將 string-literal 當作錯誤訊息顯示出來。
這樣可以怎麼使用呢?主要就是拿來做一些編譯階段就可以做的判斷了~例如在 MSDN 上給的一個例子就是用來判斷編譯器是否能夠支援 64-bit:
static_assert( sizeof(void *)==4, "64-bit code generation is not supported." );
另外在 Visual C++ Team Blog 的《Lambdas, auto, and static_assert: C++0x Features in VC10, Part 1》一文中,也有一個用來針對 template struct 做參數確認的例子:
template <int N> struct Kitten { static_assert(N < 2, "Kitten<N> requires N < 2."); };
透過這樣的寫法,可以限制 Kitten 這個 template struct 的參數 N 需要小於 2,如果遇到不符合的情況下,會直接無法編譯。
在 Heresy 來看,static_assert 應該是比較適合用在函示庫的開發上;透過使用 static_assert,可以直接在編譯階段就針對使用這個函示庫的程式做檢查,如果有問題就直接透過編譯錯誤的訊息來告訴開發者,而不需要在 run-time 再來做確認。
另外,在 open-std 的文件裡,還有許多其他例子可以參考,有興趣的話可以參考看看。
nullptr
nullptr 這個特殊的常數,是用來代表指標沒有指向任何東西用的。
在以往的 C / C++ 裡,要將指標設定不指向任何東西,都是將他的值設定為 0(NULL 實際上也只是定義為 0 的 macro)就結束了。這樣有什麼缺點的?主要就是 null pointer 和 0 之間在某些狀況下會產生混淆、無法分辨了~假設現在有兩個函式:
void f(int){ printf( "intn" ); } void f(char*){ printf( "char*n" ); }
而在這種情況下,如果用下面四種方法呼叫的話,會分別得到不同的結果:
f( NULL ); // int, compile error in GCC f( 0 ); // int f( (char*)0 ); // char* f( (void*)0 ); // compile error
也就是說,除非透過 explicit cast 的方式強制把 0 轉型成 char*(上方第三行的寫法),不然是沒辦法呼叫到 f(char*) 的。
而 nullptr 就是為了解決這樣的問題而制定出來的一個新的特別常數,型別應該是「nullptr_t」;由於他純粹就代表一個沒有指到任何東西的指標,型別也不是 int,所以就不會和 0 有所衝突了!也就是說,現在呼叫 f( nullptr ); 就可以呼叫到 f(char*) 了~
不過,要使用 nullptr 的話,還有一些地方是和使用現有的 NULL 不同的地方,像是:
-
nullptr 不能轉型成 boolean 變數,所以不能使用 if( nullptr ){…} 這樣的寫法。
-
nullptr 不是數值,所以不能用來指定成 int 的值,例如 int n = nullptr; 就是錯誤的寫法;另外他也不能用來和 int 做比較,例如 下面的寫法也是無法正確編譯的:
int n2 = 0; if( n2 == nullptr ) {...}
另外,下面也還有一些更進階的使用例子:
template<typename T> void g( T* t ); g( nullptr ); // error g( (float*)nullptr ); // deduces T = float template<typename T> void h( T t ); h( 0 ); // deduces T = int h( nullptr ); // deduces T = nullptr_t h( (float*)nullptr ); // deduces T = float*
其他細節可以參考 Open STD 的《A name for the null pointer: nullptr》一文。
你好,請問這個例子是不是有問題呢?
static_assert(
sizeof(void *)==4,
“64-bit code generation is not supported."
);
是不是應該改成assert sizeof void* == 8 ? assert失敗時顯示這個message才正確
讚讚
這邊是直接引用 MSDN 的範例: https://msdn.microsoft.com/zh-tw/library/dd293588.aspx
他這邊的意思,應該是:
這個系統只支援 32 位元,而且只考慮 32 位元和 64 位元。
如果不是 32 位元(sizeof(void *)==4)的時候,就當作是 64 位元,所以就吐不支援 64 位元的錯誤訊息。
讚讚
[…] static_assert:《C++0x:static_assert 和 nullptr》[MSDN] […]
讚讚
[…] 和 shared_ptr 都可以透過和 NULL 或 nullptr […]
讚讚
[…] static_assert:《C++0x:static_assert 和 nullptr》[MSDN] […]
讚讚
Thanks~受益匪淺~
讚讚