聲明template參數時, 前綴關鍵字class和typename可以互換;
使用關鍵字typename標識嵌套從屬類型名稱, 但不需在基類列表和成員初始化列表內使用.
從屬名稱(dependent names): 模板(template)內出現的名稱, 相依於某個模板(template)參數, 如T t;
嵌套從屬名稱(nested dependent names):從屬名稱在class內呈嵌套裝, 如T::const_iterator ci;
非從屬名稱(non-dependent names): 不依賴任何template參數的名稱, 如int value;
如果不特定指出typename, 嵌套從屬名稱, 有可能產生解析(parse)歧義.
任何時候在模板(template)中指涉一個嵌套從屬類型名稱, 需要在前一個位置, 添加關鍵字typename;
否則報錯(GCC): error: need 'typename' before 'T::xxx' because 'T' is a dependent scope
代碼:
/*
* BInsertSort.cpp
*
* Created on: 2014.4.17.
* Author: Spike
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
template<typename T>
void print2nd(const T& container) {
typename T::const_iterator iter(container.begin()); //未加typename, 報錯
++iter;
int value = *iter;
std::cout << value;
}
int main () {
vector<int> vi = {1,2,3,4,5};
print2nd(vi);
return 0;
}
輸出:
2
例外:嵌套從屬類型名稱, 如果是基類列表(base class list)和成員初值列(member initialization list)中,不使用typename;
代碼:
/*
* BInsertSort.cpp
*
* Created on: 2014.4.17
* Author: Spike
*/
#include <iostream>
#include <vector>
using namespace std;
struct Number {
Number(int x) {
std::cout << "Number = " << x << std::endl;
}
};
template<typename T>
struct Base{
typedef Number Nested;
};
template<typename T>
class Derived: public Base<T>::Nested { //不用typename
public:
explicit Derived(int x) : Base<T>::Nested(x) { //不用typename
typename Base<T>::Nested temp(7); //必須使用
}
};
int main () {
Derived<int> d(5);
return 0;
}
輸出:
Number = 5 Number = 7