2017-04-12 62 views
1

從Scott Meyers的書中,依賴於模板參數的模板中的名稱被稱爲相關名稱。 (當嵌套在一個類中的從屬名稱,我把它叫做一個嵌套從屬名稱)2個與模板相關的typename種類的區別

因此,它需要依賴名稱前使用「類型名」關鍵詞,對不對?

template<typename C> 
void print2nd(const C& container) { 
typename C::const_iterator iter(container.begin()); 
... 
} 

但是,爲什麼在這段代碼,從約祖蒂斯書,標準::向量是另一個模板的實例採取這顯然是依賴於T,他們不使用「類型名」在這裏:

template <typename T> 
class Stack { 
    (?typename?) std::vector<T> elems; 
... 
}; 

這一切看起來令人困惑,尤其是與邁耶斯的另一個例子:

template<typename IterT> 
void workWithIterator(IterT iter) { 
    typename std::iterator_traits<IterT>::value_type temp(*iter); 
... } 

他們看起來都和我一樣。你如何區分?

回答

1

當你有

typename C::const_iterator iter(container.begin()); 

const_iterator部分是取決於什麼C是一種類型。所以你需要typename來告訴編譯器C::const_iterator是一種類型。

std::vector<T> elems; 

您聲明std::vector其元素T型。那裏根本不需要typename。即使vector取決於的類型T它不是取決於T是什麼的名稱。

您可以在何時何地typenametemplateWhere and why do I have to put the "template" and "typename" keywords?

+1

,我掙扎着爬區別:)所以,當編譯器看到「C ::常量性」的任何具體類型實例/ C的替代之前的未知的,什麼是「常量性」是吧?但「std :: vector 」還取決於確切的具體T,還是其不?僅僅因爲它是實例嗎? – barney

+0

從邁爾斯又如是指類似的東西到矢量但用 「類型名稱」 關鍵字仍然: 模板<類型名稱IterT> 空隙workWithIterator(IterT ITER){ 類型名稱的std :: iterator_traits :: VALUE_TYPE溫度(* ITER); ...} 爲什麼在這裏?是什麼iterator_traits 與向量區別? – barney

+0

@barney當編譯器看到'some_name :: some_other_name'它不希望看到一個類型時'some_name'是一個模板類型。所以你使用'typename'來告訴它是一個名字,而不是像它假設的那樣是一個非名字。 – NathanOliver

2

在第一個示例中(typename C::const_iterator),const_iterator不能被編譯器直接瞭解:例如,它可能是一個靜態成員。這就是爲什麼你需要以typename爲前綴來聲明它是一種類型。

在第二個例子中,編譯器知道std::vector<T>是一種類型,甚至不知道什麼是T。這就是爲什麼typename在這種情況下不需要。

+0

究竟如何才能知道需要閱讀更多有關,是c ::爲const_iterator無法知道?是因爲它嵌套到未知類​​型C?然後,這裏是從邁爾斯另一個例子: 模板<類型名稱IterT> 空隙workWithIterator(IterT ITER){ 類型名稱的std :: iterator_traits :: VALUE_TYPE溫度(* ITER); ... } – barney

+0

@barney是的,這是因爲它嵌套在'C'中,因此編譯器很難決定什麼是'const_iterator'。如前所述,你可以在'C'中嵌入'static int const_iterator',它是一個名爲'const_iterator'的類型爲'int'的靜態成員,不是一個類型。但在這種情況下用'typename'前綴意味着「'const_iterator'是一個類型名稱」。然而,'std :: vector <>'是一個類型(它需要一個模板參數),編譯器知道,因此編譯器會在不知道'C'的確切類型的情況下計算出來。 – piwi

+1

@barney對於你提到的另一個例子('的std :: iterator_traits :: value_type'):'iterator_traits'被稱爲一個類型,但是編譯器不知道什麼是內特定的'iterator_traits '實現(因爲類可專門用於後面'IterT')的類型,所以你需要使用'typename'來表示你引用一個類型,就像'C :: const_iterator'例子。 – piwi

相關問題