//traits.h/*制定输入 - 输出类型规则*/
template <class T>
struct RtnType {typedef T return_type;//默认返回类型和输入类型一致
};template <class T>
struct RtnType<T*> {//特化,当输入的是指针类型,返回类型规定为指针原型typedef T return_type;
};template <class T>
struct RtnType<const T*> {//特化常量指针类型,当输入的是常量指针类型,返回类型规定为原型指针typedef T* return_type;
};// 你可以根据需要,特化不同的输入输出规则/*特性萃取器*/
template <class unknown_class>
struct unknown_class_traits {typedef typename unknown_class::return_type return_type;
};/*特性萃取器 —— 针对指针*/
template <class T>
struct unknown_class_traits<T*> {typedef T return_type;
};/*特性萃取其 —— 针对常量指针*/
template <class T>
struct unknown_class_traits<const T*> {typedef const T return_type;
};#define RType typename unknown_class_traits<RtnType<T>>::return_type/*决定使用哪一个类型*/
template <class T>
inline RType return_type(T) {return RType();
}/*用户统一接口*/
template <class T>
inline RType interface(T param)
{const type_info& Rtid = typeid(RType);const type_info& Tid = typeid(T);const char* Rname = Rtid.name();const char* Tname = Tid.name();bool bRet = compare_type(param, RType());//return implement(param, RType());//static dispatch here. 编译期静态分发
}/*接口默认实现*/
template <class T>
inline RType implement(T param, RType typ)
{cout << "General Version of implement" << endl;return RType();
}template <class T, T Val>
struct var_constant
{const T value = Val;using value_type = T;using type = var_constant;
};template <bool Val>
struct var_constant<bool, Val>//特化bool类型
{const bool value = Val;using value_type = bool;using type = var_constant;
};template<class T1, class T2>
struct is_same_type
{static const bool value = false;
};template<class T>
struct is_same_type<T, T>
{static const bool value = true;
};template<class T1, class T2>
inline bool compare_type(T1, T2)
{var_constant<bool, is_same_type<T1, T2>::value> bConstant;return bConstant.value;
};
//main.cpp
#include "traits.h"class A
{};struct B
{};A implement(A, A)
{cout << "use object value type version" << endl;return A();
}B implement(B*, B)
{cout << "use object raw ptr type version" << endl;return B();
}int implement(int, int)
{cout << "use raw type version." << endl;return 0;
}int implement(int*, int)
{cout << "use raw ptr version." << endl;return 0;
}int* implement(const int*, int*)
{cout << "use const raw ptr version." << endl;return 0;
}int main() {B b;A a;int value = 1;int *p = &value;const int* cp = p;A v1 = interface(a);B v2 = interface(&b);int v3 = interface(p);int* v4 = interface(cp);char ch = getchar();return 0;
}
通过一些模板技巧,使得模块内部可以根据用户输入数据类型,返回不同的数据,实现接口的统一,并在接口内实现静态分发。
另一种基于模板的静态分发,可以采用CRTP,以下是基于CRTP技术实现编译期多态的例子,仅供参考:
template<class T>
class BaseObj
{
public:inline void Interface(){return static_cast<T*>(this)->Implement();}inline void Implement(){}~BaseObj() {static_cast<T*>(this)->Destory();}inline void Destory(){}
protected:// T m_subObj;// error. 基类中不能用子类来创建成员变量,这也是c++基本要求
};class Drive :public BaseObj<Drive>
{
public:Drive() {m_handle = new int[4];}//void Implement()//解开注释,观察效果,//{// printf("Drive Implement.\r\n");//}~Drive() {printf("Drive Deconstructed.\r\n");//Don't do any clear operation, put these into Destory call}void Destory(){printf("Drive Destoryed.\r\n");delete[] m_handle;m_handle = nullptr;//important 防止Destory被重复调用导致重复释放}
private:int* m_handle;
};// 使用CRTP技术创建的不同子类对象,由于基类都是不一样的,因此不能统一放入容器中使用,可以用std::Any类型对它们进行一层包装,这样就可以放进容器了(参考:https://blog.csdn.net/yuanshenqiang/article/details/143984861)。int main()
{Drive* d1 = new Drive;BaseObj<Drive>* dd1 = new Drive;dd1->Interface();d1->Interface();delete dd1;//d1->Destory();//手动调用Destorydelete d1;//由基类的析构函数发起Destory调用return 0;
}
相比而言动态分发就是常规的虚函数——继承体系,基于该体系,可以实现各种设计模式。比如一个有趣的例子:c++的二次分发与访问者模式-CSDN博客