模板作為C++語(yǔ)言特性的一個(gè)重要組成部分,被廣泛用在范式編程中,在標(biāo)準(zhǔn)庫(kù)中經(jīng)常可以看到一些非常讓人拍案叫絕的模板技術(shù)。在課程中接觸到這些技術(shù),做個(gè)整理和總結(jié)。
一. variadic templates
實(shí)現(xiàn)這一特性的方法是通過(guò)遞歸算法,一次處理一個(gè)目標(biāo)參數(shù),直到處理到最后的模板參數(shù)作為遞歸基返回。
以標(biāo)準(zhǔn)庫(kù)的hash函數(shù)為例
template<typename... Types>
size_t hash_all(const Types&... args)
{
size_t seed=0;
hash_val(seed,args...); //進(jìn)入計(jì)算
return seed;
}
template<typename T,typename... Types>
void hash_val(size_t &seed,
const T& val,const Types&... args)
{
//處理第一個(gè)模板參數(shù)
hash_combine(seed,val);
//遞歸
hash_val(sed,args...);
}
//處理到最后一個(gè)參數(shù)
template<typename T>
void hash_val(size_t &seed,const T& val)
{
hash_combine(seed,val);
}
//對(duì)模板參數(shù)進(jìn)行處理
#include <functional>
template<typename T>
void hash_combine(size_t &seed,const T &val)
{
seed^=std::hash<T>()(val)+0x9e3779b9
+(seed<<6)+(seed>>2);
}
二. tuple的參數(shù)處理
template<typename... Values> class tuple;
//繼承鏈的最頂端
template<> class tuple<>{};
template<typename Head,typename... Tail>
class tuple<Head,Tail...>
:private tuple<Tail...>
{
typedef tuple<Tail...> inherited;
public:
tuple(){}
tuple(Head v,Tail... vtail)
:m_head(v),inherited(vtail...){}
typename Head::type head() { return m_head; }
inherited &tail() { return *this; }
protected:
Head m_head;
};
tuple的設(shè)計(jì)是利用繼承鏈的最低端,在構(gòu)造函數(shù)中對(duì)它的直接基類進(jìn)行初始化,而它的基類又對(duì)基類的直接基類進(jìn)行初始化,不斷遞歸,直到直接基類是個(gè)空類為止。
//以tuple(1,2.3,"hello")為例
tuple<int,float,string> t(1,2.3,"hello");
t.head() ; //1
t.tail(); //(2.3,"hello")
t.tail().head(); //2.3
三. type traits的設(shè)計(jì)
標(biāo)準(zhǔn)庫(kù)為我們提供了很多的type traits的模板類型,我們可以用來(lái)初始化獲得類型的相關(guān)信息。
以 is_void為例,用來(lái)判斷是不是void類型,解決思路是把對(duì)象的一些其他類型去除再來(lái)判斷是否為void
//去除 const 的屬性
template<typename T>
struct remove_const
{
typedef T type;
};
template<typename T>
struct remove_const<T const>
{
typedef T type;
};
//去除 volatile 的屬性
template<typename T>
struct remove_volatile
{
typedef T type;
};
template<typename T>
struct remove_volatile<T volatile>
{
typedef T type;
};
//去除 const volatile 的屬性
template<typename T>
struct remove_cv
{
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};
template<typename>
struct __is_void_helper
:public false_type{};
template<>
struct __is_void_helper<void>
:public true_type{};
template<typename T>
//最后繼承 false_type 或 true_type
struct is_void
:public __is_void_helper<typename remove_cv<T>::type>::type{};
運(yùn)用到模板的特化解決問(wèn)題,很多思路都是可以借鑒的