2012-01-02 106 views
2

C++被認爲是靜態類型的。我明白那個。模板:靜態類型還是動態?

我不明白這是如何適用於模板。

這裏是不能在編譯時確定一個類型的一個簡單的例子:

template <typename... t> 
struct foo { 
    using type = typename foo<t..., t...>::type; 
}; 

foo<int>::type x; // type of x cannot be determined without running meta-program 

我相信存在這樣的情況是不可能的檢測類型錯誤不解決停機問題。

所以我的問題是,爲什麼不考慮動態類型的模板?

+0

有沒有元程序運行,只是一些類型實例,所有發生在C++程序的**編譯時**。 – Xeo 2012-01-02 03:01:59

+0

@Xeo它不能實例化任何東西,因爲它不能確定類型 – Pubby 2012-01-02 03:03:49

+2

我假設編譯器仍然會在編譯時間中試圖找出這種類型。任何證明違背這一假設? – 2012-01-02 03:04:20

回答

7

靜態/動態類型通常是指最終編譯程序運行時的行爲,而不是元程序的行爲。由於foo<int>::type在達到最終編譯程序的運行時間時已解決,因此它被認爲是靜態類型。

至於模板元程序,可以認爲它是使用鴨子打字,這是一種動態打字。但是,請注意,仍然存在靜態類型(在C++ 11之前版本中) - 模板上的模板參數數量可以被視爲元函數的元類型,用於生成具體類型(這是一個值就元程序而言)。

通過比較,在Haskell中,他們有一個層次類型的概念。你有典型的類型 - 像函數,整數等等。然後你有'種類',它描述類型的類型和元函數。例如,Haskell種類* -> * -> *可以指鍵到值的映射,很像C++中的template<typename Key, typename Value> class Map。任何關於語言是靜態還是動態輸入的決定都必須引用您所指的層次結構的哪一層。從歷史上看,C++模板在初次設計時從未真正被認爲是元程序,所以這類術語在C++中沒有被廣泛使用,但仍然可以應用相同的概念。

+0

我不明白元程序是如何動態輸入的。模板使用結構化類型,這是一種靜態類型。 – 2012-01-02 03:26:04

+0

@ R.MartinhoFernandes,當您引用與模板參數相關的類型時,動態類型會發揮作用。例如'std :: vector '其中'T'是模板參數;編譯器必須驗證存在「T :: foo」,是一種類型,並且如果是適當的類型,動態地(即在執行模板元程序時,而不是在執行模板元程序之前) – bdonlan 2012-01-02 03:29:40

+0

否, 'T :: foo'是一個值,而不是一個類型。這就是爲什麼你需要'typename'作爲消歧器:知道沒有實例化(即運行元程序)。 – 2012-01-02 03:31:59