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++,伴我同行。