2012-06-28 16 views
5

我注意到,當實例化爲typedef'ed時,類模板中的靜態斷言不會被觸發。應該用typedef觸發static_assert嗎?

#include <type_traits> 

template <typename T> 
struct test_assert 
{ 
    static_assert(std::is_same< T, int >::value, "should fail"); 
}; 

typedef test_assert<float> t; 

該代碼編譯沒有錯誤。如果我嘗試創建一個實例,然後斷言失敗:

t obj; // error: static assertion failed: "should fail" 

最後,如果我false更換條件,則斷言失敗,即使我不實例化類模板:

template <typename T> 
struct test_assert 
{ 
    static_assert(false, "always fails"); 
}; 

我在gcc-4.5.1和gcc-4.7.0上試過這段代碼。這種行爲是否正常?編譯器在什麼時候驗證靜態斷言?我猜想涉及到兩階段查找,但typedef不應該觸發第二階段?

+0

+1。很好的問題。 :-) – Nawaz

回答

9

我在gcc-4.5.1和gcc-4.7.0上試過這段代碼。這種行爲是否正常?

在什麼時候時,編譯器應該驗證靜態斷言?

這是一個有趣的問題。在實例化期間,這將是非依賴名稱的第一階段查找和依賴於模板參數的斷言的第二查找階段。

猜測涉及到兩階段查找,但不應該typedef觸發 第二階段?

模板是按需編譯的,typedef只是爲模板創建一個別名,不會觸發實例化。請看下面的代碼:

template <typename T> class unique_ptr; 
typedef unique_ptr<int> int_unique_ptr; 

模板只宣佈,但足夠了類型定義,因爲它僅生成類型的別名。另一方面,如果你創建了一個類型的對象,那麼模板必須被實例化(再次按需,成員函數將不會被實例化)。

+0

謝謝,這是我的想法。我很驚訝,因爲我從來沒有注意到在幾個月的模板元編程。事實上,在TMP中,'typedef'通常訪問一個嵌套類型,觸發實例化。 –

+0

+1很好的答案! – Nawaz

相關問題