條款typename的雙重定義
宣告關鍵字class和typename可互換
假設你這樣宣告一個迭代器 C::const_iterator iter(container.begin());
這將不是一個有效的c++代碼,
因為 C::const_iterator如果不是一個型別呢?如果C 有個成員變數恰好命名為const_iterator,如果他碰巧是個全域變數呢?
當然這聽上去有點瘋狂,但確實是有可能的,而撰寫c++決議器的人必須操心所有可能的輸入,包括這么瘋狂的輸入
如果你想在template中指涉一個嵌套從屬型別名稱,就必須在緊鄰它的前一個位置放上關鍵字typename
下面是代碼環節:
#include <iostream>
#include<vector>
using namespace std;
/*
template<typename C>
void print2nd(const C& container)
{
if (container.size() >= 2)
{
typename C::const_iterator iter(container.begin());
++iter;
int value = *iter;
cout << value;
}
}
*/
template<class C>
void print2nd(const C& container)
{
if (container.size() >= 2)
{
class C::const_iterator iter(container.begin());
++iter;
int value = *iter;
cout << value;
}
}
int main()
{
vector<int> res;
res.push_back(1);
res.push_back(2);
print2nd(res);
return 0;
}
運行結果:
但有一例外,typename不可以出現在base classes list內的嵌套從屬型別名稱之前,
也不能在成員初值列中

其他都可以
#include <iostream>
#include<vector>
using namespace std;
template<typename T>
class MyNested
{
public:
MyNested(T x) :value(x) { cout << value << endl; }
T value;
};
template<typename T>
class Base
{
public:
typedef MyNested<T> Nested;
};
template<typename T>
class Dervied:public Base<typename T>::Nested
{
public:
explicit Dervied(int x) : Base<T>::Nested(x)
{
typename Base<T>::Nested temp(5);
}
private:
};
int main()
{
Dervied<int> d(7);
return 0;
}
運行結果:

最后
當使用特性類(traits class)時, 必須使用typename, 如
#include <vector>
#include <iostream>
using namespace std;
template<typename T>
void workWithIter(T iter) {
typedef typename std::iterator_traits<T>::value_type value_type; //使用typename
value_type temp(*iter);
std::cout << "temp = " << temp << std::endl;
}
int main() {
vector<int> ai = { 1,2,3,4,5 };
vector<int>::iterator aiIter = ai.begin();
workWithIter(aiIter);
return 0;
}
運行結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286993.html
標籤:其他
上一篇:記錄我學習STM32踩的坑
