概念:
Metadata
:能够在编译期被操作的东西就是元数据,分成两类:类型和非类型,这两类都可以做为模板参数。整数类型,函数的指针或引用,成员指针(这些都可以转化成整数,因此是合法的)
Metafunction
:类模板,它的所有参数都是类型;
类,有公共的可访问的内嵌类;
多态:允许使用不同的参数类型的性质就是多态,字面上即“多种形式的能力”;
在C++中,多态有两种:静态多态,即编译期多态;动态多态,即运行期多态;
编译期多态使得我们可以在编译期做出选择,而这正是我们所向往追求的。
Boost的type traits library:这是MPL的基石
以下代码抽自boost/或自己的替代实现,知其然,知其所以然,我们后面使用到的时候才可以了然于胸
1. primary type
is_xxx系列的metafunction具有成员value,而且我们只关心成员value的值为true/false
template
<
bool
x
>
struct
bool_

...
{
static bool const value = x;
typedef bool_<x> type;
typedef bool value_type;

operator bool() const ...{ return x; }
};
typedef bool_
<
false
>
false_;
typedef bool_
<
true
>
true_;
is_xxx系列派生自bool_,下面逐一给出is_xxx的实现
is_integral通过对integral类型进行特化达到
template
<
typename type
>

struct
is_integral : false_
...
{}
;
//
即默认所有类型均不是integral类型
//
at this moment, variadic template still has nothing to do with this condition
template
<
bool
arg0,
bool
arg1,
bool
arg2
=
false
,
bool
arg3
=
false
,
bool
arg4
=
false
,
bool
arg5
=
false
,
bool
arg6
=
false
,
bool
arg7
=
false
,
bool
arg8
=
false
,
bool
arg9
=
false
>
struct
ice_or

...
{
static const bool value = arg0+arg1+arg2+arg3+arg4+arg5+arg6+arg7+arg8+arg9;
}
;

template
<
bool
arg0,
bool
arg1,
bool
arg2
=
true
,
bool
arg3
=
true
,
bool
arg4
=
true
,
bool
arg5
=
true
,
bool
arg6
=
true
,
bool
arg7
=
true
,
bool
arg8
=
true
,
bool
arg9
=
true
>
struct
ice_and

...
{
static const bool value = arg0*arg1*arg2*arg3*arg4*arg5*arg6*arg7*arg8*arg9;
}
;
// 然后对可枚举的integral类型进行特化,其中还有对应的const/volatile/const volatile版本
template
<>
struct
is_integral
<
char
>
: true_...
...
{}
;

template
<>
struct
is_integral
<
const
char
>
: true_...
...
{}
;

template
<>
struct
is_integral
<
volatile
char
>
: true_...
...
{}
;

template
<>
struct
is_integral
<
const
volatile
char
>
: true_...
...
{}
;
C++中的integral类型有以下:
bool / char / unsigned char / signed char / wchar_t / short / unsigned short / int / unsigned int / long / unsigned long / long long / unsigned long long
分别对以上类型进行特化,我们就可以得到完整的is_integral
is_float的实现跟is_integral相同,c++中,float类型只有float/double/long double,还有对应的const/volatile/const volatile版本;
template
<
typename type
>

struct
is_void : false_
...
{}
;

template
<>
struct
is_void
<
void
>
: true_
...
{}
;

template
<>
struct
is_void
<
const
void
>
: true_
...
{}
;

template
<>
struct
is_void
<
const
volatile
void
>
: true_
...
{}
;
Is_function使用variadic template实现,否则需要根据函数的参数个数一一进行特化,很麻烦,c++0x直接支持variadic template, conceptgcc已经实现了variadic template功能
template
<
typename type
>

struct
is_function : false_
...
{}
;
template
<
typename retType, typename ... argType
>

struct
is_function
<
retType (
*
)(argType...)
>
: true_
...
{}
;
template
<
typename type
>

struct
is_member_function : false_
...
{}
;
template
<
typename retType, typename classType, typename ... argType
>

struct
is_member_function
<
retType (classType::
*
)(argType...)
>
: true_
...
{}
;
template
<
typename type
>
struct
is_array : false_...
...
{}
;

template
<
typename type,
int
N
>
struct
is_array
<
type[N]
>
: true_...
...
{}
;

template
<
typename type
>
struct
is_array
<
type[]
>
: true_...
...
{}
;
//
然后是对应的const/volatile/const volatile版本true_{};
i
s_member_pointer的实现类似于
is_function,其中,
is_member_pointer分为两种:
1,类成员数据指针;
2,类成员函数指针
template
<
typename type
>

struct
is_member_pointer :false_
...
{}
;
template
<
typename dataType, typename classType
>

struct
is_member_pointer
<
dataType classType::
*>
: true_
...
{}
;
template
<
typename retType, typename classType, … argType
>

struct
is_member_pointer
<
retype (classType::
*
)(argType…)
>
: true_
...
{}
;
//
还有对应的const/volatile/const volatile版本
template
<
typename type
>

struct
is_pointer : false_
...
{}
;
template
<
typename type
>

struct
is_ponter
<
type
*>
: true_
...
{}
;
template
<
typename type
>

struct
is_pointer : is_function
<
type
>
...
{}
;
template
<
typename type
>

struct
is_pointer : is_member_pointer
<
type
>
...
{}
;
template
<
typename type
>

struct
is_reference : false_
...
{}
;
template
<
typename type
>

struct
is_reference
<
type
&>
: true_
...
{}
;
//
还有对应的const/volatile/const volatile版本
C++中的类类型包括:class/struct/union定义的类型,对于类类型,可以定义其类成员指针,包括成员数据指针及成员函数指针,boost就是利用这个性质来区分是否为类类型
template
<
typename type
>
char
class_helper(
int
type::
*
);
template
<
typename type
>
int
class_helper(...);

template
<
typename type
>
struct
is_class_helper

...
{
static const bool value = sizeof(class_helper<type>(0))==sizeof(char) ? true : false;
}
;

template
<
typename type
>

struct
is_class : bool_
<
is_class_helper
<
type
>
::value
>
...
{}
;
现在,剩下is_union/is_enum未实现,这几个比较麻烦,需要编译器提供相当的支持,boost提供保守的支持,就是将is_union/is_enum都默认为false_。
2. secondary type
template
<
typename type
>

struct
is_arithmetic : boos_
...
<ice_or<is_integral<type>::value, is_float<type>::value>::value>{}
;
is_fundamental的实现:包含算术类型和void类型
template
<
typename type
>

struct
is_fundamental: bool_
...
<ice_or<is_arithmetic<type>::value, is_void<type>::value>::value>{}
;
根据C++标准,复合类型包括数组/函数/指针/引用/类类型/枚举/成员指针,或者说,除了基础类型,其它的都是复合类型,而基础类型则只包括算术类型和void类型。
template
<
typename type
>

struct
is_compound: bool_
<!
is_fundamental
<
type
>
::value
>
...
{}
;
在C++中,对象是指除了函数和引用之外的所有东西
template
<
typename type
>

struct
is_object: bool_
<!ice_or<is_function<type>::value, is_reference<type>::value>::value>{};
根据C++定义,标量类型包括算术类型/枚举类型/指针类型
template
<
typename type
>

struct
is_scalar: bool_
<
ice_or<is_arithmetic<type>::value, is_pointer<type>::value, is_member_pointer<type>::value>::value>{};
枚举类型需要编译器的支持,boost中保守地将其置为false_。
3. type property
alignment_of用于编译期计算出类型的对齐长度,alginment_of还需要对void进行特化
template
<
typename type
>

struct
alignment_of_helper
...
{
char c;
type t;
}
;
template
<
typename type
>

struct
alignment_of
...
{
static const int value = (sizeof(alignment_of_helper)-sizeof(c))<size(type)?(sizeof(alignment_of_helper)-sizeof(c)):sizeof(type);
}
;
is_empty
template
<
typename type
>

struct
is_empty_helper : type
...
{}
;
template
<
typename type,
bool
isClass
=
false
>
struct
is_empty_helper1

...
{
static const bool value = false;
}
;
template
<
typename type
>
struct
is_empty_helper1
<
type,
true
>

...
{
static const bool value = (sizeof(is_empty_helper<type>) == sizeof(type));
}
;
template
<
typename type
>

struct
is_empty : bool_
<
is_empty_helper1
<
type, is_class
<
type
>
::value
>
...
{}
;
如果类类型是多态的,即类具有虚函数
template
<
typename Type,
bool
isClass
=
false
>
struct
is_polymorphic_helper

...
{
static const bool value = false;
}
;

template
<
typename Type
>
struct
is_polymorphic_helper
<
Type,
true
>

...
{
typedef typename remove_cv<Type>::type ncvType;

struct base1 : ncvType...{~base1()...{}};

struct base2 : ncvType...{virtual ~base2()...{}};
static const bool value = (sizeof(base1) == sizeof(base2));
}
;

template
<
typename Type
>

struct
is_polymorphic : bool_
<
is_polymorphic_helper
<
Type, is_class
<
Type
>
::value
>
::value
>
...
{}
;
4. more type property
has_nothrow_assign / has_nothrow_constructor / has_nothrow_copy / has_trivial_assign / has_trivial_constructor / has_trivial_copy / is_pod / is_stateless的实现,都需要编译器支持
5. relationship between types
template
<
typename type1, typename type2
>

struct
is_same : false_
...
{}
;
template
<
typename type
>

struct
is_same
<
type,type
>
: true_
...
{}
is_convertible
template
<
typename to
>
char
convertible_helper(to);
template
<
typename to
>
int
convertible_helper(...);
template
<
typename from, typename to
>
struct
is_convertible_helper

...
{
static from m;
static const bool value = (sizeof(convertible_helper<to>(m)) == sizeof(char));
}
;

template
<
typename from, typename to
>

struct
is_convertible : bool_
<
is_convertible_helper
<
from,to
>
::value
>
...
{}
;
is_base_and_derived
template
<
typename
base
, typename derived
>

struct
is_base_and_derived : bool_
<
ice_and
<
is_class
<
base
>
::value, is_class
<
derived
>
::value, is_convertible
<
derived,
base
>
::value
>
::value
>
...
{}
;
6. type transformation
template
<
typename Type
>
struct
remove_const

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
remove_const
<
const
Type
>

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
remove_const
<
const
volatile
Type
>

...
{
typedef Type volatile type;
}
;

template
<
typename Type
>
struct
remove_volatile

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
remove_volatile
<
volatile
Type
>

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
remove_volatile
<
const
volatile
Type
>

...
{
typedef Type const type;
}
;
template
<
typename Type
>
struct
remove_cv

...
{
typedef typename remove_volatile<typename remove_const<Type>::type>::type type;
}
;

template
<
typename Type
>
struct
remove_reference

...
{
typedef Type type;
}
;

template
<
typename Type
>
struct
remove_reference
<
Type
&>

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
remove_pointer

...
{
typedef Type type;
}
;

template
<
typename Type
>
struct
remove_pointer
<
Type
*>

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
add_reference

...
{
typedef Type& type;
}
;

template
<
typename Type
>
struct
add_reference
<
Type
&>

...
{
typedef Type type;
}
;
template
<
typename Type
>
struct
add_pointer

...
{
typedef Type* type;
}
;

template
<
typename Type
>
struct
add_const

...
{
typedef Type const type;
}
;

template
<
typename Type
>
struct
add_const
<
const
Type
>

...
{
typedef Type type;
}
;
以上的type_trait实现只在conceptgcc下面测试通过并且测试是相当简单的,给出测试用例,如果需要使用type_trait,我们仍然需要使用boost中的mpl
struct
foo
...
{}
;


struct
vfoo
...
{virtual ~vfoo()...{}}
;


struct
base
...
{}
;

struct
derived :
base
...
{}
;

void
bar(
int
v,
char
b)

...
{}

int
main()

...
{
typedef int (*funcptr)(int,char);
typedef void (foo::*memfunptr)(int,char);
printf("funcptr is pointer : %d ", is_pointer<funcptr>::value);
printf("int is pointer : %d ", is_pointer<int>::value);
printf("int* is pointer : %d ", is_pointer<int*>::value);
printf("int is class : %d ", is_class<int>::value);
printf("foo is class : %d ", is_class<foo>::value);
printf("int is array : %d ", is_array<int>::value);
printf("int[] is array : %d ", is_array<int[]>::value);
printf("const int[] is array : %d ", is_array<const int[]>::value);
printf("const int[10] is array : %d ", is_array<const int[10]>::value);
printf("const int*[10] is array : %d ", is_array<const int*[10]>::value);
printf("int is reference : %d ", is_reference<int>::value);
printf("int& is reference : %d ", is_reference<int&>::value);
printf("const int& is reference : %d ", is_reference<const int&>::value);

printf("memfunptr is member function pointer : %d ", is_member_pointer<memfunptr>::value);
printf("int is member function pointer : %d ", is_member_pointer<int>::value);
printf("int is arithmetic : %d ", is_arithmetic<int>::value);
printf("int* is arithmetic : %d ", is_arithmetic<int*>::value);
printf("double is fundamental : %d ", is_fundamental<double>::value);
printf("void is fundamental : %d ", is_fundamental<void>::value);
printf("void* is fundamental : %d ", is_fundamental<void*>::value);
printf("foo is compound : %d ", is_compound<foo>::value);
printf("int is compound : %d ", is_compound<int>::value);
printf("int[] is compound : %d ", is_compound<int[]>::value);
printf("int is object : %d ", is_object<int>::value);
printf("int& is object : %d ", is_object<int&>::value);
printf("foo is object : %d ", is_object<foo>::value);
printf("funcptr is object : %d ", is_object<funcptr>::value);
printf("int is scalar : %d ", is_scalar<int>::value);
printf("int& is scalar : %d ", is_scalar<int&>::value);
printf("foo alignment : %d ", alignment_of<foo>::value);
printf("void alignment : %d ", alignment_of<void>::value);
printf("long double alignment : %d ", alignment_of<long double>::value);
printf("int is empty : %d ", is_empty<int>::value);
printf("foo is empty : %d ", is_empty<foo>::value);
printf("foo is polymorphic : %d ", is_polymorphic<foo>::value);
printf("int is polymorphic : %d ", is_polymorphic<int>::value);
printf("vfoo is polymorphic : %d ", is_polymorphic<vfoo>::value);
printf("int float is convertible : %d ", is_convertible<int,float>::value);
printf("int* float* is convertible : %d ", is_convertible<int*,float*>::value);
printf("double float is convertible : %d ", is_convertible<double,float>::value);
printf("foo vfoo is convertible : %d ", is_convertible<foo, vfoo>::value);
printf("base derived is convertible : %d ", is_convertible<base, derived>::value);
printf("derived base is convertible : %d ", is_convertible<derived, base>::value);
return 0;
}
附带上部分习题解答:
#include
<
typeinfo
>
#include
<
cstdio
>
#include
<
stdbool.h
>
#include
<
string
.h
>
#include
<
iostream
>
using
namespace
std;

template
<
typename type1, typename type2
>
struct
is_same

...
{
const static bool value = false;
}
;


template
<
typename type
>
struct
is_same
<
type,type
>

...
{
const static bool value = true;
}
;

#if
0
template
<
typename Type
>
struct
add_const_ref

...
{
typedef const Type& type;
}
;

template
<
typename Type
>
struct
add_const_ref
<
const
Type
>

...
{
typedef const Type& type;
}
;

template
<
typename Type
>
struct
add_const_ref
<
volatile
Type
>

...
{
typedef const Type& type;
}
;

template
<
typename Type
>
struct
add_const_ref
<
const
volatile
Type
>

...
{
typedef const Type& type;
}
;

template
<
typename Type
>
struct
add_const_ref
<
Type
&>

...
{
typedef Type type;
}
;


template
<
typename Type
>
struct
add_const_ref
<
const
Type
&>

...
{
typedef Type type;
}
;


template
<
typename Type
>
struct
add_const_ref
<
volatile
Type
&>

...
{
typedef Type type;
}
;


template
<
typename Type
>
struct
add_const_ref
<
const
volatile
Type
&>

...
{
typedef Type type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type

...
{
typedef c type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
const
c, x, y
>

...
{
typedef typename replace_type<c,x,y>::type const type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
volatile
c, x, y
>

...
{
typedef typename replace_type<c,x,y>::type volatile type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
const
volatile
c, x, y
>

...
{
typedef typename replace_type<c,x,y>::type const volatile type;
}
;

template
<
typename x, typename y
>
struct
replace_type
<
x,x,y
>

...
{
typedef y type;
}
;

template
<
typename x, typename y
>
struct
replace_type
<
const
x,x,y
>

...
{
typedef y const type;
}
;

template
<
typename x, typename y
>
struct
replace_type
<
volatile
x,x,y
>

...
{
typedef y volatile type;
}
;

template
<
typename x, typename y
>
struct
replace_type
<
const
volatile
x,x,y
>

...
{
typedef y const volatile type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
c
&
, x, y
>

...
{
typedef typename replace_type<c,x,y>::type& type;
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
c
*
, x, y
>

...
{
typedef typename replace_type<c,x,y>::type* type;
}
;

template
<
typename c, typename x, typename y,
int
size
>
struct
replace_type
<
c[size],x,y
>

...
{
typedef typename replace_type<c,x,y>::type tempType;
typedef tempType type[size];
}
;

template
<
typename c, typename x, typename y
>
struct
replace_type
<
c(
*
)(),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef retType (*type)();
}
;

template
<
typename c, typename arg1, typename x, typename y
>
struct
replace_type
<
c(
*
)(arg1),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef typename replace_type<arg1,x,y>::type arg1Type;
typedef retType (*type)(arg1Type);
}
;

template
<
typename c, typename arg1, typename arg2, typename x, typename y
>
struct
replace_type
<
c(
*
)(arg1,arg2),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef typename replace_type<arg1,x,y>::type arg1Type;
typedef typename replace_type<arg2,x,y>::type arg2Type;
typedef retType (*type)(arg1Type,arg2Type);
}
;

// 原来想通过variadic template实现,尝试后未能成功
template
<
typename c, typename ClassType, typename x, typename y
>
struct
replace_type
<
c(ClassType::
*
)(),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef typename replace_type<ClassType,x,y>::type classType;
typedef retType (classType::*type)();
}
;

template
<
typename c, typename ClassType, typename arg1, typename x, typename y
>
struct
replace_type
<
c(ClassType::
*
)(arg1),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef typename replace_type<ClassType,x,y>::type classType;
typedef typename replace_type<arg1,x,y>::type arg1Type;
typedef retType (classType::*type)(arg1Type);
}
;

template
<
typename c, typename ClassType, typename arg1, typename arg2, typename x, typename y
>
struct
replace_type
<
c(ClassType::
*
)(arg1,arg2),x,y
>

...
{
typedef typename replace_type<c,x,y>::type retType;
typedef typename replace_type<ClassType,x,y>::type classType;
typedef typename replace_type<arg1,x,y>::type arg1Type;
typedef typename replace_type<arg2,x,y>::type arg2Type;
typedef retType (classType::*type)(arg1Type,arg2Type);
}
;
#endif

template
<
typename Type
>

struct
type_descriptor
...
{
static const char *name;
operator const char*()

...{
return name;
}
}
;


template
<
typename Type
>
const
char
*
type_descriptor
<
Type
>
::name
=
"
Unknow type
"
;
template
<>
const
char
*
type_descriptor
<
char
>
::name
=
"
char
"
;
template
<>
const
char
*
type_descriptor
<
const
char
>
::name
=
"
const char
"
;
template
<>
const
char
*
type_descriptor
<
volatile
char
>
::name
=
"
volatile char
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
char
>
::name
=
"
const volatile char
"
;
template
<>
const
char
*
type_descriptor
<
unsigned
char
>
::name
=
"
unsigned char
"
;
template
<>
const
char
*
type_descriptor
<
const
unsigned
char
>
::name
=
"
const unsigned char
"
;
template
<>
const
char
*
type_descriptor
<
volatile
unsigned
char
>
::name
=
"
volatile unsigned char
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
unsigned
char
>
::name
=
"
const volatile unsigned char
"
;
template
<>
const
char
*
type_descriptor
<
signed
char
>
::name
=
"
signed char
"
;
template
<>
const
char
*
type_descriptor
<
const
signed
char
>
::name
=
"
const signed char
"
;
template
<>
const
char
*
type_descriptor
<
volatile
signed
char
>
::name
=
"
volatile signed char
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
signed
char
>
::name
=
"
const volatile signed char
"
;
template
<>
const
char
*
type_descriptor
<
short
>
::name
=
"
short
"
;
template
<>
const
char
*
type_descriptor
<
const
short
>
::name
=
"
const short
"
;
template
<>
const
char
*
type_descriptor
<
volatile
short
>
::name
=
"
volatile short
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
short
>
::name
=
"
const volatile short
"
;
template
<>
const
char
*
type_descriptor
<
unsigned
short
>
::name
=
"
unsigned short
"
;
template
<>
const
char
*
type_descriptor
<
const
unsigned
short
>
::name
=
"
const unsigned short
"
;
template
<>
const
char
*
type_descriptor
<
volatile
unsigned
short
>
::name
=
"
volatile unsigned short
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
unsigned
short
>
::name
=
"
const volatile unsigned short
"
;
template
<>
const
char
*
type_descriptor
<
int
>
::name
=
"
int
"
;
template
<>
const
char
*
type_descriptor
<
const
int
>
::name
=
"
const int
"
;
template
<>
const
char
*
type_descriptor
<
volatile
int
>
::name
=
"
volatile int
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
int
>
::name
=
"
const volatile int
"
;
template
<>
const
char
*
type_descriptor
<
unsigned
int
>
::name
=
"
unsigned int
"
;
template
<>
const
char
*
type_descriptor
<
const
unsigned
int
>
::name
=
"
const unsigned int
"
;
template
<>
const
char
*
type_descriptor
<
volatile
unsigned
int
>
::name
=
"
volatile unsigned int
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
unsigned
int
>
::name
=
"
const volatile unsigned int
"
;
template
<>
const
char
*
type_descriptor
<
long
>
::name
=
"
long
"
;
template
<>
const
char
*
type_descriptor
<
const
long
>
::name
=
"
const long
"
;
template
<>
const
char
*
type_descriptor
<
volatile
long
>
::name
=
"
volatile long
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
long
>
::name
=
"
const volatile long
"
;
template
<>
const
char
*
type_descriptor
<
unsigned
long
>
::name
=
"
unsigned long
"
;
template
<>
const
char
*
type_descriptor
<
const
unsigned
long
>
::name
=
"
const unsigned long
"
;
template
<>
const
char
*
type_descriptor
<
volatile
unsigned
long
>
::name
=
"
volatile unsigned long
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
unsigned
long
>
::name
=
"
const volatile unsigned long
"
;
template
<>
const
char
*
type_descriptor
<
long
long
>
::name
=
"
long long
"
;
template
<>
const
char
*
type_descriptor
<
const
long
long
>
::name
=
"
const long long
"
;
template
<>
const
char
*
type_descriptor
<
volatile
long
long
>
::name
=
"
volatile long long
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
long
long
>
::name
=
"
const volatile long long
"
;
template
<>
const
char
*
type_descriptor
<
unsigned
long
long
>
::name
=
"
unsigned long long
"
;
template
<>
const
char
*
type_descriptor
<
const
unsigned
long
long
>
::name
=
"
const unsigned long long
"
;
template
<>
const
char
*
type_descriptor
<
volatile
unsigned
long
long
>
::name
=
"
volatile unsigned long long
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
unsigned
long
long
>
::name
=
"
const volatile unsigned long long
"
;
template
<>
const
char
*
type_descriptor
<
float
>
::name
=
"
float
"
;
template
<>
const
char
*
type_descriptor
<
const
float
>
::name
=
"
const float
"
;
template
<>
const
char
*
type_descriptor
<
volatile
float
>
::name
=
"
volatile float
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
float
>
::name
=
"
const volatile float
"
;
template
<>
const
char
*
type_descriptor
<
double
>
::name
=
"
double
"
;
template
<>
const
char
*
type_descriptor
<
const
double
>
::name
=
"
const double
"
;
template
<>
const
char
*
type_descriptor
<
volatile
double
>
::name
=
"
volatile double
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
double
>
::name
=
"
const volatile double
"
;
template
<>
const
char
*
type_descriptor
<
long
double
>
::name
=
"
long double
"
;
template
<>
const
char
*
type_descriptor
<
const
long
double
>
::name
=
"
const long double
"
;
template
<>
const
char
*
type_descriptor
<
volatile
long
double
>
::name
=
"
volatile long double
"
;
template
<>
const
char
*
type_descriptor
<
const
volatile
long
double
>
::name
=
"
const volatile long double
"
;

template
<
typename Type
>

struct
type_descriptor
<
Type
*>
...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "pointer to ");
strcat(name, type_descriptor<Type>());
return name;
}
}
;

template
<
typename Type
>

struct
type_descriptor
<
Type
&>
...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "reference to ");
strcat(name, type_descriptor<Type>());
return name;
}
}
;

template
<
typename Type,
int
size
>

struct
type_descriptor
<
Type[size]
>
...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "array of ");
strcat(name, type_descriptor<Type>());

char temp[256] = ...{0};
sprintf(temp, " which size = %d", size);
strcat(name, temp);
return name;
}
}
;

template
<
typename retType
>
struct
type_descriptor
<
retType(
*
)()
>

...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "function return ");
strcat(name, type_descriptor<retType>());
strcat(name, " and has no argument");
return name;
}
}
;

template
<
typename retType, typename argType
>
struct
type_descriptor
<
retType(
*
)(argType)
>

...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "function return ");
strcat(name, type_descriptor<retType>());
strcat(name, " and with ");
strcat(name, type_descriptor<argType>());
strcat(name, " as first argument");
return name;
}
}
;

template
<
typename retType, typename arg1Type, typename arg2Type
>
struct
type_descriptor
<
retType(
*
)(arg1Type, arg2Type)
>

...
{
operator const char*()

...{
static char name[1024];
strcpy(name, "function return ");
strcat(name, type_descriptor<retType>());
strcat(name, " and with ");
strcat(name, type_descriptor<arg1Type>());
strcat(name, " as first argument, ");
strcat(name, type_descriptor<arg2Type>());
strcat(name, " as second argument");
return name;
}
}
;

int
main()

...
{
cout<<"type_descriptor<const int* (*)(char& (*)(short), double*)>" << type_descriptor<const int* (*)(char& (*)(short), double*)>();
printf("add_const_ref<int>::type = %s ", typeid(add_const_ref<int>::type).name());
printf("add_const_ref<int>::type == const int& : %d ", is_same<add_const_ref<int>::type, const int&>::value);
printf("add_const_ref<volatile int>::type == const int& : %d ", is_same<add_const_ref<volatile int>::type, const int&>::value);
printf("add_const_ref<volatile int&>::type == int : %d ", is_same<add_const_ref<volatile int&>::type, int>::value);

printf("replace_type<int,int,char>::type == char : %d ", is_same<replace_type<int,int,char>::type, char>::value);
printf("replace_type<const int,int,char>::type == char : %d ", is_same<replace_type<const int,int,char>::type, const char>::value);
printf("replace_type<int(*)(int,char),int,short>::type == short(*)(short,char) : %d ", is_same<replace_type<int(*)(int,char),int,short>::type, short(*)(short,char)>::value);
printf("replace_type<int(*)(const int,int (*)()),int,short>::type == short(*)(const short, short(*)()) : %d ", is_same<replace_type<int(*)(const int, int(*)()),int,short>::type, short(*)(const short,short(*)())>::value);
printf("replace_type<int[10],int,char>::type == char[10] : %d ", is_same<replace_type<int[10],int,char>::type, char[10]>::value);
printf("replace_type<int[10],int,char>::type = %s ", typeid(replace_type<int[10],int,char>::type).name());
printf("replace_type<int[10],char,char>::type == int[10] : %d ", is_same<replace_type<int[10],char,char>::type, int[10]>::value);
printf("replace_type<int[10],char,char>::type = %s ", typeid(replace_type<int[10],char,char>::type).name());
return 0;
}