1、非變異算法與變異算法概述
非變異算法是指一系列模板函數,在不改變操作對象的前提下對元素進行處理,如查找、子序列搜索、統計、匹配等,具體有for_each、find、adjacent_find、find_first_of、count、count_if、mismatch、equal、search;變異算法指改變容器中對象的操作,有copy、swap、transform、replace、fill、generate、remove、unique、reserve、rotate、randomshuffle、partion等
2、什么時候用到typename
typename cannot be used outside a template declaration;
聲明template參數時, 前綴關鍵字class和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
代碼
代碼:
[cpp]view plaincopy
/*
*?BInsertSort.cpp
*
*??Created?on:?2014.4.17.
*??????Author:?Spike
*/
#include?
#include?
#include?
usingnamespacestd;
template
voidprint2nd(constT&?container)?{
typenameT::const_iterator?iter(container.begin());//未加typename,?報錯
++iter;
intvalue?=?*iter;
std::cout?<<?value;
}
intmain?()?{
vector?vi?=?{1,2,3,4,5};
print2nd(vi);
return0;
}
輸出:
2
例外:嵌套從屬類型名稱, 如果是基類列表(base class list)和成員初值列(member initialization list)中,不使用typename;
代碼:
[cpp]view plaincopy
/*
*?BInsertSort.cpp
*
*??Created?on:?2014.4.17
*??????Author:?Spike
*/
#include?
#include?
usingnamespacestd;
structNumber?{
Number(intx)?{
std::cout?<<"Number?=?"<<?x?<<?std::endl;
}
};
template
structBase{
typedefNumber?Nested;
};
template
classDerived:publicBase::Nested?{//不用typename
public:
explicitDerived(intx)?:?Base::Nested(x)?{//不用typename
typenameBase::Nested?temp(7);//必須使用
}
};
intmain?()?{
Derived?d(5);
return0;
}
輸出:
[plain]view plaincopy
Number?=?5
Number?=?7
當使用特性類(traits class)時, 必須使用typename, 如
代碼:
[cpp]view plaincopy
/*
*?BInsertSort.cpp
*
*??Created?on:?2014.4.17
*??????Author:?Spike
*/
#include?
#include?
usingnamespacestd;
template
voidworkWithIter(T?iter)?{
typedeftypenamestd::iterator_traits::value_type?value_type;//使用typename
value_type?temp(*iter);
std::cout?<<"temp?=?"<<?temp?<<?std::endl;
}
intmain?()?{
std::array?ai?=?{1,2,3,4,5};
std::array::iterator?aiIter?=?ai.begin();
workWithIter(aiIter);
return0;
}
輸出:
[plain]view plaincopy
temp?=?1