您的位置:首页 > 编程语言

模板元编程:接受一个复合类型C作为第一个参数,并将其中的类型A替换为类型B

2010-09-01 21:14 183 查看
原题:http://topic.csdn.net/u/20100831/16/a6bf13c3-8002-4c5a-9746-b827deb20686.html?85864" target=_blank> http://topic.csdn.net/u/20100831/16/a6bf13c3-8002-4c5a-9746-b827deb20686.html?21825
template<typename C, typename A, typename B>
struct type_replace;
//接受一个复合类型C作为第一个参数,并将其中的类型A替换为类型B
typedef type_replace< void*, void, int > :: result_type t1; // int*
typedef type_replace< int const* [10], int const, long > :: result_type t2; // long* [10]
typedef type_replace< char& (*)(char&, const char*), char&, long > :: result_type t3;// long (*)(long, const char*)


定义:

1. IsSameT<T1,T2>:

判断T1和T2是否是类型相同

//IsSameT.hxx
#pragma  once
template<typename T1,typename T2>
struct IsSameT
{
enum { eYes = 0 };
};
template<typename T>
struct IsSameT<T,T>
{
enum { eYes = 1 };
};


2. IsBaseType<T>:

Base Type是指T去掉一个指针,或者引用,或者数组,或者常量修饰符后用于构造T的类型.

如果T为基本类型,这IsBaseType<T>::eYes为1否则为0

//IsBaseT.hxx

#pragma once
template<typename T>
struct IsBaseT
{
typedef T T_base_type;
enum{ eYes = true};
};

/***********************************************************/

template<typename T>
struct IsBaseT<T*>
{
typedef T T_base_type;
enum{ eYes = false};

};

template<typename T>
struct IsBaseT<T&>
{
typedef T T_base_type;
enum{ eYes = false};
};

template<typename T>
struct IsBaseT<T const>
{
typedef T T_base_type;
enum{ eYes = false};
};

template<typename T>
struct IsBaseT<T volatile>
{
typedef T T_base_type;
enum{ eYes = false};
};

template<typename T>
struct IsBaseT<T const volatile>
{
typedef T T_base_type;
enum{ eYes = false};
};

template<typename T,int SIZE>
struct IsBaseT<T [SIZE]>
{
typedef T T_base_type;
enum{ eYes = false};
};

template<typename T>
struct IsBaseT<T []>
{
typedef T T_base_type;
enum{ eYes = false};
};


3.IsFunctionT<T>:

IsFunctionT用于判断T是否是函数指针类型.

基本原理:数组元素不能为void,引用或者函数类型.

//IsFunctionT.hxx
#pragma once
template<typename T>
struct IsFunctionT {

private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename U> static One Test(...);
template<typename U> static Two Test(U (*)[1]);
template<typename U> static Two Test(int C::*); //抽象类
public:
enum { eYes = sizeof(Test<T>(0)) == 1 };
};
template<typename T>
struct IsFunctionT<T&> {enum { Yes = 0 }; };
template<> struct IsFunctionT<void>		 { enum{ eYes = 0 }; };
template<> struct IsFunctionT<void const>{ enum{ eYes = 0 }; };


4.IsSuperT<Super,B>:

此函数用于判断Super是否是B的超类型.

Super是B的超类型是指C可以使用B用指针,引用,数组,const等通过有限次构造出来

//IsSuperT.hxx

#pragma once
#include "IsBaseT.hxx"

template<typename Super,typename B,int>
struct IsSuperTWrapper;

template<typename Super,typename B>
struct IsSuperT
{
enum{ eYes = IsSuperTWrapper<Super, B ,IsBaseT<Super>::eYes>::eYes};
};

/******************************************************************/
template<typename Super,typename B,int>
struct IsSuperTWrapper
{
typedef typename IsBaseT<Super>::T_base_type T_base_type;
enum{ eYes =IsSuperTWrapper< T_base_type,B,IsBaseT<T_base_type>::eYes >::eYes};
};

template<typename Super,typename B>
struct IsSuperTWrapper<Super,B,1>
{
enum{ eYes = 0};
};

template<typename Super>
struct IsSuperTWrapper<Super,Super,1>
{
enum{ eYes = 1};
};

template<typename Super>
struct IsSuperTWrapper<Super,Super,0>
{
enum{ eYes = 1};
};

template<typename Super,typename B>
struct IsSuperTWrapper<Super const volatile,B const,0>
{
enum {eYes = 1};
};
template<typename Super,typename B>
struct IsSuperTWrapper<Super const volatile,B volatile,0>
{
enum {eYes = 1};
};


5.TypeReplace<C,A,B>

接受一个复合类型C作为第一个参数,并将其中的类型A替换为类型B

//TypeReplace.hxx

#pragma once
#include "IsSuperT.hxx"
#include "IsFunctionT.hxx"
#include "IsSameT.hxx"

template<typename C, typename A, typename B,int _Is_SuperT>
struct TypeReplaceWrapper;

template<typename C, typename A, typename B>
struct TypeReplace
{
typedef typename TypeReplaceWrapper<C,A,B,IsSuperT<C,A>::eYes>::result_type result_type;
};

/********************** C是A的超类的情况 Begin******************************************/

template<typename C, typename A, typename B,int SameT>
struct SuperTypeReplaceWrapper;

template<typename C, typename A, typename B>
struct TypeReplaceWrapper<C,A,B,1>
{
typedef typename SuperTypeReplaceWrapper<C,A,B,IsSameT<C,A>::eYes>::result_type result_type;
};

#define SUPER_TYPE_REPLACE_WRAPPER(exp)												/
template<typename C, typename A, typename B>										/
struct SuperTypeReplaceWrapper<C exp,A,B,0>											/
{																					/
typedef typename SuperTypeReplaceWrapper<C,A,B,IsSameT<C,A>::eYes>::result_type exp result_type;/
}

SUPER_TYPE_REPLACE_WRAPPER(*);
SUPER_TYPE_REPLACE_WRAPPER(&);
SUPER_TYPE_REPLACE_WRAPPER(const);
SUPER_TYPE_REPLACE_WRAPPER(volatile);
SUPER_TYPE_REPLACE_WRAPPER(const volatile);
//数组
template<typename C, typename A, typename B,int SIZE>
struct SuperTypeReplaceWrapper<C [SIZE],A,B,0>
{
typedef typename SuperTypeReplaceWrapper<C,A,B,IsSameT<C,A>::eYes>::result_type (result_type) [SIZE] ;
};
//空数组
template<typename C, typename A, typename B>
struct SuperTypeReplaceWrapper<C [],A,B,0>
{
typedef typename SuperTypeReplaceWrapper<C,A,B,IsSameT<C,A>::eYes>::result_type(result_type) [] ;
};

//结束条件: C跟A的类型相同
template<typename A, typename B>
struct SuperTypeReplaceWrapper<A,A,B,1>
{
typedef B result_type;
};

template<typename C,typename A, typename B>
struct SuperTypeReplaceWrapper<C const volatile,A const,B,0>
{
typedef B volatile result_type;
};

template<typename C,typename A, typename B>
struct SuperTypeReplaceWrapper<C const volatile,A volatile,B,0>
{
typedef B const result_type;
};

/********************** C不是A的超类的情况 Begin******************************************/
#define NOSUPER_TYPE_REPLACE_WRAPPER(exp)										/
template<typename C, typename A, typename B>									/
struct TypeReplaceWrapper<C exp,A,B,0>											/
{																				/
typedef typename TypeReplaceWrapper<C,A,B,0>::result_type exp result_type;	/
}
NOSUPER_TYPE_REPLACE_WRAPPER(*);		//指针特化
NOSUPER_TYPE_REPLACE_WRAPPER(&);		//引用特化
NOSUPER_TYPE_REPLACE_WRAPPER(const);	//const特化
NOSUPER_TYPE_REPLACE_WRAPPER(volatile);	//const特化
NOSUPER_TYPE_REPLACE_WRAPPER(volatile const);	//const特化

//数组特化
template<typename C, typename A, typename B,int SIZE>
struct TypeReplaceWrapper<C [SIZE],A,B,0>
{
typedef typename TypeReplaceWrapper<C,A,B,0>::result_type  (result_type)[SIZE];
};

//空数组特化
template<typename C, typename A, typename B>
struct TypeReplaceWrapper<C[] ,A,B,0>
{
typedef typename TypeReplaceWrapper<C,A,B,0>::result_type  (result_type)[];
};

template<typename C, typename A, typename B>
struct TypeReplaceWrapper<C,A,B,0>
{
typedef C result_type;
};

#define RESUALT_TYPE_DEF(exp) typedef typename  TypeReplace< exp ,A,B>::result_type T_##exp

#include "TypeReplace4Func.hxx"
#include "TypeReplace4MemPtr.hxx"
#include "TypeReplace4Templ.hxx"
/********************** C不是A的超类的情况 End******************************************/


6. TypeReplace4Func.hxx: 对函数类型进行特化,用于替换函数中的参数

//TypeReplace4Func.hxx
#pragma once
template<typename C, typename A, typename B,int _Is_SuperT>
struct TypeReplaceWrapper;
//对于函数类型
//0参数
template<typename A, typename B,typename ResType>
struct TypeReplaceWrapper< ResType (),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
typedef T_ResType (result_type)();
};
//1参数
template<typename A, typename B,typename ResType,typename T1>
struct TypeReplaceWrapper< ResType (T1),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
typedef T_ResType (result_type)(T_T1);
};
//2参数
template<typename A, typename B,typename ResType,typename T1,typename T2>
struct TypeReplaceWrapper< ResType (T1,T2),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
typedef T_ResType (result_type)(T_T1,T_T2);
};
//3参数
template<typename A, typename B,typename ResType,typename T1,typename T2, typename T3>
struct TypeReplaceWrapper< ResType (T1,T2,T3),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
typedef T_ResType (result_type)(T_T1,T_T2,T_T3);
};
//4参数
template<typename A, typename B,typename ResType,typename T1,typename T2, typename T3,typename T4>
struct TypeReplaceWrapper< ResType (T1,T2,T3,T4),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
RESUALT_TYPE_DEF(T4);
typedef T_ResType (result_type)(T_T1,T_T2,T_T3,T_T4);
};


7. TypeReplace4MemPtr.hxx:对成员指针(包括数据成员指针和成员函数指针)进行特化

//TypeReplace4MemPtr.hxx
#pragma once
template<typename C, typename A, typename B,int _Is_SuperT>
struct TypeReplaceWrapper;
//数据成员指针类型特化
template<typename Class, typename A, typename B,typename DataType>
struct TypeReplaceWrapper<DataType Class::*,A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(DataType);
typedef T_DataType (T_Class::*result_type);
};
//成员函数类型,0参数
template<typename Class,typename A, typename B, typename ResType>
struct TypeReplaceWrapper< ResType (Class::*)(),A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(ResType);
typedef T_ResType (T_Class::*result_type)();
};
//成员函数类型,1参数
template<typename Class,typename A, typename B, typename ResType,typename T1>
struct TypeReplaceWrapper< ResType (Class::*)(T1),A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
typedef T_ResType (T_Class::*result_type)(T_T1);
};
//成员函数类型,2参数
template<typename Class,typename A, typename B, typename ResType,typename T1,typename T2>
struct TypeReplaceWrapper< ResType (Class::*)(T1,T2),A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
typedef T_ResType (T_Class::*result_type)(T_T1,T_T2);
};
//成员函数类型,3参数
template<typename Class,typename A, typename B, typename ResType,typename T1,typename T2,typename T3>
struct TypeReplaceWrapper< ResType (Class::*)(T1,T2,T3),A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
typedef T_ResType (T_Class::*result_type)(T_T1,T_T2,T_T3);
};
//成员函数类型,4参数
template<typename Class,typename A, typename B, typename ResType,typename T1,typename T2,typename T3,typename T4>
struct TypeReplaceWrapper< ResType (Class::*)(T1,T2,T3,T4),A,B,0>
{
RESUALT_TYPE_DEF(Class);
RESUALT_TYPE_DEF(ResType);
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
RESUALT_TYPE_DEF(T4);
typedef T_ResType (T_Class::*result_type)(T_T1,T_T2,T_T3,T_T4);
};


8.TypeReplace4Templ.hxx: 对模板类进行特化

//TypeReplace4Templ.hxx
#pragma once
template<typename C, typename A, typename B,int _Is_SuperT>
struct TypeReplaceWrapper;
template<template <typename> class Class,typename A, typename B,typename T1>
struct TypeReplaceWrapper<Class<T1> ,A,B,0>
{
RESUALT_TYPE_DEF(T1);
typedef Class<T_T1> result_type;
};
template<template <typename,typename> class Class,typename A, typename B,typename T1,typename T2>
struct TypeReplaceWrapper<Class<T1,T2> ,A,B,0>
{
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
typedef Class<T_T1,T_T2> result_type;
};
template<template <typename,typename,typename> class Class,typename A, typename B,typename T1,typename T2,typename T3>
struct TypeReplaceWrapper<Class<T1,T2,T3> ,A,B,0>
{
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
typedef Class<T_T1,T_T2,T_T3> result_type;
};
template<template <typename,typename,typename,typename> class Class,typename A, typename B,typename T1,typename T2,typename T3,typename T4>
struct TypeReplaceWrapper<Class<T1,T2,T3,T4> ,A,B,0>
{
RESUALT_TYPE_DEF(T1);
RESUALT_TYPE_DEF(T2);
RESUALT_TYPE_DEF(T3);
RESUALT_TYPE_DEF(T4);
typedef Class<T_T1,T_T2,T_T3,T_T4> result_type;
};


main.cpp: 测试代码

// Main.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <typeinfo>
#include <vector>
using namespace std;
#include "typereplace.hxx"
#include "TypeReplace4Templ.hxx"
class Test
{
};
class Test1
{
};
int main(int argc, char* argv[])
{
//普通类型
cout<<typeid( TypeReplace<int***,int**,long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int***,int*****,long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int &,int,long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<Test*****,Test**,long>::result_type).name()<<endl;
//数据成员类型
cout<<typeid( TypeReplace<int ** Test::*,Test,Test1>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int ** Test::*,int,Test1>::result_type).name()<<endl;
//成员函数类型
cout<<typeid( TypeReplace<int ** (Test::*)(int*******,int),int**, long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int ** (Test::*)(int*******,int),Test, Test1>::result_type).name()<<endl;
//函数类型
cout<<typeid( TypeReplace<int ** (int*******,int),int**, long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<void (int*******,int),int, long>::result_type).name()<<endl;
//函数作为参数
cout<<typeid( TypeReplace<int ** (int*******,int(int***)),int**, long>::result_type).name()<<endl;
//数组以及空数组
cout<<typeid( TypeReplace<int[],int**, long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int**[],int**, long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int[1000],int**, long>::result_type).name()<<endl;
cout<<typeid( TypeReplace<int**[1000],int**, long>::result_type).name()<<endl;
//模板类
cout<<typeid( TypeReplace<auto_ptr<int****>, int** ,long>::result_type).name()<<endl;

return 0;
}


输出:

long *
int * * *
long
long * * *
int * * Test1::*
class Test1 * * Test::*
long (__thiscall Test::*)(long * * * * *,int)
int * * (__thiscall Test1::*)(int * * * * * * *,int)
long __cdecl(long * * * * *,int)
void __cdecl(long * * * * * * *,long)
long __cdecl(long * * * * *,int (__cdecl*)(long *))
int [0]
long [0]
int [1000]
long [1000]
class std::auto_ptr<long * *>
请按任意键继续. . .


或许大家对第三个和第四个的输出有疑问,觉得上面的代码不能正确处理引用和const的情况

事实上代码是完全正确的,只是输出有点问题,这是因为在VC中输出typeid(DataType).name的时候,DataType中包含的const和&是不输出的,如果你不信不妨可以用VS2005试一下输出 cout<<typeid( int const &).name()<<endl; 你一定会为为这代码居然是输出int而大跌眼镜

补充:

对于不定参数的函数,本文就暂时不给1个参数以上的实现了,但是对于这个很容易扩充

以下是对于 Type Func(...)类型的不定参数的实现,其它实现请使用copy/paste功能

//0参数,不定参数,对于其它版本的不定参数暂时不给实现
template<typename A, typename B,typename ResType>
struct TypeReplaceWrapper< ResType (...),A,B,0>
{
RESUALT_TYPE_DEF(ResType);
typedef T_ResType (result_type)();
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐