compressed_pair的實現一共依靠三個模板類:
Compressed_pair_imp
Compressed_pair_switch
Compress_pair
在這裏:
Compressed_pair_imp是compressed_pair的基類
Compressed_pair_switch是compressed_compressed_imp生成定向模板的選擇器
Compress_pair所謂的壓縮技術不過是通過繼承的方式來進行壓縮(這個是核心),如果我們直接在類內構造一個空類對象,由於c++是不允許一個佔字節的空類的存在,編譯器往往會給空類加一個char或者int,這完全取決於編譯器的實現。
template<class T1, class T2>
class compress_pair{
private:
Firsttype ft;
Secondtype st
};<span lang="en-US" style="font-family: Calibri;">//</span><span lang="zh-CN" style="font-family: SimSun;">單純的構造對象是不能實現壓縮效果的</span>
首先我們先實現compressed_pair_switch:
我們同過兩個類是否相同,是否爲空,分成6中情況討論。
#include<type_traits>
template<class T1 ,class T2 ,bool isSame,bool t1Empty ,bool t2Empty >
struct compress_pair_switch;
//當兩個類不相同的時候,且t1爲空時,t2不爲空的時候。
template<class T1, class T2>
struct compress_pair_switch< T1, T2,false,true,false > {
static const int value = 1;
};
//當兩個類不相同的時候,且t1不爲空時,t2爲空的時候。
template<class T1, class T2>
struct compress_pair_switch<T1,T2,false,false,true >
{
static const int value = 2;
};
在我們將Compressed_pair_switch實現後,我們就需要實現Compressed_pair_imp,Compressed_pair_imp是compressed_pair的具體實現,也就是最最核心的地方。
在這裏我們根據模板定向選擇器來定向生成適用於不同情況來生成compress_pair_imp(偏特化)
#pragma once
#include"compress_pair_switch_ref.h"
//這種僅有類聲明的模板類只能同過我們指定生成的偏特化模板來進行初始化
template<class T1, class T2 ,int Switch>
class compress_pair_imp_ref;
//當兩個類不相同的時候,且t1爲空時,t2不爲空的時候。
template<class T1 ,class T2>
class compress_pair_imp_ref<T1,T2,1> :protected std::remove_cv<T1>::type { //保護繼承
public:
using Firsttype = T1;
using Secondtype = T2 ;
typedef typename std::add_const<T1>::type Firstconsttype;
typedef typename std::add_const<T2>::type Secondconsttype;
typedef compress_pair_imp_ref FirstType;
//這個就是一個所謂的障眼法。用於對外界忽略內部實現。
public:
//compress_pair_imp_ref();
compress_pair_imp_ref(Firsttype t1, Secondtype t2) :std::remove_cv<T1>::type(t1), noSempty(t2) {} //順序不可顛倒
explicit compress_pair_imp_ref(Firsttype t1):Firsttype(t1){}
explicit compress_pair_imp_ref(Secondtype t2):noSempty(t2){}
public:
FirstType first() { return *this; } //注意這個返回值
Secondtype second() { return noSempty; }
private:
Secondtype noSempty;
};
//當兩個類不相同的時候,且t1不爲空時,t2爲空的時候。
template<class T1, class T2>
class compress_pair_imp_ref< T1, T2, 2> :protected std::remove_cv<T2>::type { //保護繼承
public:
typedef T1 Firsttype;
typedef T2 Secondtype;
typedef const T1 Firstconsttype;
typedef const T2 Secondconsttype;
typedef compress_pair_imp_ref SecondType;
public:
compress_pair_imp_ref();
compress_pair_imp_ref(Firsttype t1, Secondtype t2) :noFempty(t1), std::remove_cv<T2>::type(t2) {} //順序不可顛倒
explicit compress_pair_imp_ref(Firsttype t1) :noFempty(t1) {}
explicit compress_pair_imp_ref(Secondtype t2) :std::remove_cv<T2>::type(t2){}
public:
Firsttype first() { return noSempty; }
Secondtype second() { return *this; } //注意這個返回值
private:
Firsttype noFempty;
};
最後我們同過compress_pair繼承compress_pair_imp,同時使用compress_pair_switch來進行定向選擇。
#pragma once
#include"compress_pair_imp_ref.h"
template<class T1 ,class T2>
class compress_pair_ref
<span style="white-space:pre"> </span>:public compress_pair_imp_ref<T1,T2,compress_pair_switch<T1,T2,
std::is_same<T1,T2>::value,
std::is_empty<T1>::value,
std::is_empty<T2>::value>::value>{
public:
typedef compress_pair_imp_ref<T1, T2, compress_pair_switch<T1, T2,
std::is_same<T1, T2>::value,
std::is_empty<T1>::value,
std::is_empty<T2>::value>::value> base;
typedef T1 Firsttype;
typedef T2 Secondtype;
public:
compress_pair_ref();
compress_pair_ref(Firsttype t1, Secondtype t2) :base(t1, t2) {}
compress_pair_ref(Firsttype t1) :base(t1) {}
compress_pair_ref(Secondtype t2) :base(t2) {}
};
注意類的繼承使用:
class compress_pair_ref
:public compress_pair_imp_ref<T1,T2,compress_pair_switch<T1,T2,
std::is_same<T1,T2>::value,
std::is_empty<T1>::value,
std::is_empty<T2>::value>::value>
c++,伴我同行。