Boolan C++ 第十周 三種巧妙的模板技術(shù)

模板作為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)題,很多思路都是可以借鑒的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容