2010-06-23 73 views
6

這個語法被用作一個答案的一部分this question請幫我理解這句法(實現用C靜態斷言++)

template <bool> 
struct static_assert; 

template <> 
struct static_assert<true> {}; // only true is defined 

#define STATIC_ASSERT(x) static_assert<(x)>() 

我不明白語法。它是如何工作的?

假設我

STATIC_ASSERT(true); 

它被轉化爲

static_assert<true>(); 

現在怎麼辦?

+0

:) – GManNickG 2010-06-23 08:07:59

回答

13
STATIC_ASSERT(true); 

確實意味着

static_assert<true>(); 

將計算得到什麼。 static_assert<true>只是一個沒有任何成員的空白結構。 static_assert<true>()創建該結構的對象並且不將它存儲在任何地方。

這只是編譯和不做任何事情。

在另一方面

STATIC_ASSERT(false); 

裝置

static_assert<false>(); 

這導致編譯錯誤。 static_assert沒有專業false。所以使用一般形式。但一般形式如下:

template <bool> 
struct static_assert; 

這只是一個聲明的結構,而不是它的定義。因此,static_assert<false>()會導致編譯錯誤,因爲它會嘗試創建未定義的結構對象。

+0

+1優秀的解釋 – fingerprint211b 2010-06-23 10:22:07

2

嗯,我想這是關於模板專業化。 STATIC_ASSERT(true)會成功編譯,因爲有一個「static_assert < true>」的定義(不只是聲明)。

STATIC_ASSERT(false)將被編譯器拒絕,因爲只有「static_assert < false>」聲明並且沒有定義。

更新:爲Visual Studio,STATIC_ASSERT(真)是好的,但STATIC_ASSERT(假)觸發錯誤: 「錯誤C2514: 'static_assert < __formal>':類沒有構造[與__formal =假]」

9

static_assert<true>();,使該

template <> 
struct static_assert<true> {} 

模板結構專業化臨時對象的創建正在做的 - 調用構造函數,以後這兩個將被優化有望消除,因爲他們什麼都不做析構函數。由於true只有專業化版本,並且沒有模板結構的通用版本,因此所有結構爲static_assert<false>();的結構都不會編譯。

+0

謝謝你的解釋,我也發現自己迷失在這個語法中。 – PeterK 2010-06-23 07:02:15

4

在表達式

static_assert<true>(); 

static_assert<true>以來是一種類型,它將調用的static_assert<true>構造。由於static_assert<true>專門用於空結構,所以不會有任何影響。


然而,在

static_assert<false>(); 

,因爲是static_assert<false>沒有專業化,一般定義

template <bool> 
struct static_assert; 

將被使用。但在這裏,static_assert<B>型號是不完整。所以調用構造函數static_assert<B>將導致編譯錯誤。


因此,這種被稱爲「靜態斷言」彷彿表達式求false,類似normal assert() function能殺死在運行時程序中的語句將中止編譯。