编写一个元函数
template<typename C, typename A, typename B>struct type_replace;
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*)
#include <cstddef>
template <typename,typename> struct is_same { enum { value = false }; };
template <typename T> struct is_same <T, T> { enum { value = true }; };
template <bool, typename, typename> struct select;
template <typename T, typename U> struct select <true ,T,U> { typedef T type; };
template <typename T, typename U> struct select <false,T,U> { typedef U type; };
// General
template <typename T, typename X, typename Y>
struct replace { typedef typename select <is_same <T,X>::value,Y,T>::type type; };
// Simple composite
template <typename T, typename Y> struct replace <T&,T&,Y> { typedef Y type; };
template <typename T, typename Y> struct replace <T*,T*,Y> { typedef Y type; };
template <typename T, typename Y> struct replace <T[],T[],Y> { typedef Y type; };
template <typename T, typename Y, size_t S>
struct replace <T[S],T[S],Y> { typedef Y type; };
// Compound composite
template <typename T, typename X, typename Y>
struct replace <T&,X,Y>
{ typedef typename replace <T,X,Y>::type& type; };
template <typename T, typename X, typename Y>
struct replace <T*,X,Y>
{ typedef typename replace <T,X,Y>::type* type; };
template <typename T, typename X, typename Y>
struct replace <T[],X,Y>
{ typedef typename replace <T,X,Y>::type type [] ; };
template <typename T, typename X, typename Y, size_t size>
struct replace <T[size],X,Y>
{ typedef typename replace <T,X,Y>::type type [size]; };
// Functions
template <typename R, typename X, typename Y>
struct replace <R(),X,Y>
{ typedef typename replace <R,X,Y>::type (type) (); };
template <typename R, typename A1, typename X, typename Y>
struct replace <R(A1),X,Y>
{ typedef typename replace <R,X,Y>::type (type) (typename replace <A1,X,Y>::type); };
template <typename R, typename A1, typename A2, typename X, typename Y>
struct replace <R(A1,A2),X,Y>
{
typedef typename replace <R,X,Y>::type (type)
(typename replace <A1,X,Y>::type, typename replace <A2,X,Y>::type);
};
// Pointers to member functions
template <typename C, typename R, typename X, typename Y>
struct replace <R (C::*) (),X,Y>
{ typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type) (); };
template <typename C, typename R, typename A1, typename X, typename Y>
struct replace <R (C::*) (A1),X,Y>
{
typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type)
(typename replace <A1,X,Y>::type);
};
template <typename C, typename R, typename A1, typename A2, typename X, typename Y>
struct replace <R (C::*) (A1,A2),X,Y>
{
typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type)
(typename replace <A1,X,Y>::type, typename replace <A2,X,Y>::type);
};
// Pointers to const member functions
template <typename C, typename R, typename X, typename Y>
struct replace <R (C::*) () const,X,Y>
{ typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type) () const; };
template <typename C, typename R, typename A1, typename X, typename Y>
struct replace <R (C::*) (A1) const,X,Y>
{
typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type)
(typename replace <A1,X,Y>::type) const;
};
template <typename C, typename R, typename A1, typename A2, typename X, typename Y>
struct replace <R (C::*) (A1,A2) const,X,Y>
{
typedef typename replace <R,X,Y>::type (replace <C,X,Y>::type :: * type)
(typename replace <A1,X,Y>::type, typename replace <A2,X,Y>::type) const;
};
// For member function tests
struct test1 { };
struct test2 { };
int main (int,char**)
{
// LZ's tests
static_assert(is_same <int*,
replace <void*,void,int>::type>::value,"");
static_assert(is_same <long*[10],
replace <int const*[10],int const,long>::type>::value,"");
static_assert(is_same <long,
replace <char&,char&,long>::type>::value,"");
static_assert(is_same <long(*)(long,const char*),
replace <char&(*)(char&,const char*),char&,long>::type>::value,"");
static_assert(is_same <long(*)(long(*)(long),const char*),
replace <char&(*)(char&(*)(char&),const char*),char&,long>::type>::value,"");
// Simple type
static_assert(is_same <int,
replace <char,char,int>::type>::value,"");
static_assert(is_same <int,
replace <char const,char const,int>::type>::value,"");
static_assert(is_same <int,
replace <char volatile,char volatile,int>::type>::value,"");
static_assert(is_same <int,
replace <char const volatile,char volatile const,int>::type>::value,"");
// Simple pointer type
static_assert(is_same <int,
replace <char*,char*,int>::type>::value,"");
static_assert(is_same <int,
replace <char const*,char const*,int>::type>::value,"");
static_assert(is_same <int,
replace <char volatile*,char volatile*,int>::type>::value,"");
static_assert(is_same <int,
replace <char const volatile*,char volatile const*,int>::type>::value,"");
// Simple reference type
static_assert(is_same <int,
replace <char&,char&,int>::type>::value,"");
static_assert(is_same <int,
replace <char const&,char const&,int>::type>::value,"");
static_assert(is_same <int,
replace <char volatile&,char volatile&,int>::type>::value,"");
static_assert(is_same <int,
replace <char const volatile&,char volatile const&,int>::type>::value,"");
// Simple dynamic array type
static_assert(is_same <int,
replace <char[],char[],int>::type>::value,"");
static_assert(is_same <int,
replace <char const[],char const[],int>::type>::value,"");
static_assert(is_same <int,
replace <char volatile[],char volatile[],int>::type>::value,"");
static_assert(is_same <int,
replace <char const volatile[],char volatile const[],int>::type>::value,"");
// Simple static array type
static_assert(is_same <int,
replace <char[10],char[10],int>::type>::value,"");
static_assert(is_same <int,
replace <char const[10],char const[10],int>::type>::value,"");
static_assert(is_same <int,
replace <char volatile[10],char volatile[10],int>::type>::value,"");
static_assert(is_same <int,
replace <char const volatile[10],char volatile const[10],int>::type>::value,"");
// Composite pointer type
static_assert(is_same <int*,
replace <char*,char,int>::type>::value,"");
static_assert(is_same <int*,
replace <char const*,char const,int>::type>::value,"");
static_assert(is_same <int*,
replace <char volatile*,char volatile,int>::type>::value,"");
static_assert(is_same <int*,
replace <char const volatile*,char volatile const,int>::type>::value,"");
// Composite reference type
static_assert(is_same <int&,
replace <char&,char,int>::type>::value,"");
static_assert(is_same <int&,
replace <char const&,char const,int>::type>::value,"");
static_assert(is_same <int&,
replace <char volatile&,char volatile,int>::type>::value,"");
static_assert(is_same <int&,
replace <char const volatile&,char volatile const,int>::type>::value,"");
// Composite dynamic array type
static_assert(is_same <int[],
replace <char[],char,int>::type>::value,"");
static_assert(is_same <int[],
replace <char const[],char const,int>::type>::value,"");
static_assert(is_same <int[],
replace <char volatile[],char volatile,int>::type>::value,"");
static_assert(is_same <int[],
replace <char const volatile[],char volatile const,int>::type>::value,"");
// Composite static array type
static_assert(is_same <int[10],
replace <char[10],char,int>::type>::value,"");
static_assert(is_same <int[10],
replace <char const[10],char const,int>::type>::value,"");
static_assert(is_same <int[10],
replace <char volatile[10],char volatile,int>::type>::value,"");
static_assert(is_same <int[10],
replace <char const volatile[10],char volatile const,int>::type>::value,"");
// Functions
static_assert(is_same <int(),
replace <char(),char,int>::type>::value,"");
static_assert(is_same <int(int),
replace <char(char),char,int>::type>::value,"");
static_assert(is_same <int(int*,int&),
replace <char(char*,char&),char,int>::type>::value,"");
// Function pointers
static_assert(is_same <int(*)(),
replace <char(*)(),char,int>::type>::value,"");
static_assert(is_same <int(*)(int),
replace <char(*)(char),char,int>::type>::value,"");
static_assert(is_same <int(*)(int*,int&),
replace <char(*)(char*,char&),char,int>::type>::value,"");
// Function references
static_assert(is_same <int(&)(),
replace <char(&)(),char,int>::type>::value,"");
static_assert(is_same <int(&)(int),
replace <char(&)(char),char,int>::type>::value,"");
static_assert(is_same <int(&)(int*,int&),
replace <char(&)(char*,char&),char,int>::type>::value,"");
return 0;
}
template<typename C, typename A, typename B, typename D>struct replace_aux{ typedef D result_type;};template<typename A, typename B, typename D>struct replace_aux<A, A, B, D>{ typedef B result_type;};template<typename C, typename A, typename B>struct type_replace{ typedef typename replace_aux<C, A, B, C>::result_type result_type;};template<typename C, typename A, typename B>struct type_replace<C*, A, B>{ typedef typename type_replace<C, A, B>::result_type replaced_type; typedef replaced_type* composited_type; typedef typename replace_aux<C*, A, B, composited_type>::result_type result_type;};template<typename C, typename A, typename B>struct type_replace<C&, A, B>{ typedef typename type_replace<C, A, B>::result_type replaced_type; typedef replaced_type& composited_type; typedef typename replace_aux<C&, A, B, composited_type>::result_type result_type;};template<typename C, typename A, typename B>struct type_replace<C const, A, B>{ typedef typename type_replace<C, A, B>::result_type replaced_type; typedef replaced_type const composited_type; typedef typename replace_aux<C const, A, B, composited_type>::result_type result_type;};template<int size, typename C, typename A, typename B>struct type_replace<C[size], A, B>{ typedef typename type_replace<C, A, B>::result_type replaced_type; typedef replaced_type composited_type[size]; typedef typename replace_aux<C[size], A, B, composited_type>::result_type result_type;};template<typename R, typename A, typename B>struct type_replace<R (*)(), A, B>{ typedef typename type_replace<R, A, B>::result_type ret_type; typedef ret_type (*composited_type)(); typedef typename replace_aux<R (*)(), A, B, composited_type>::result_type result_type;};template<typename R, typename P, typename A, typename B>struct type_replace<R (*)(P), A, B>{ typedef typename type_replace<R, A, B>::result_type ret_type; typedef typename type_replace<P, A, B>::result_type param_type; typedef ret_type (*composited_type)(param_type); typedef typename replace_aux<R (*)(P), A, B, composited_type>::result_type result_type;};template<typename R, typename P1, typename P2, typename A, typename B>struct type_replace<R (*)(P1, P2), A, B>{ typedef typename type_replace<R, A, B>::result_type ret_type; typedef typename type_replace<P1, A, B>::result_type param1_type; typedef typename type_replace<P2, A, B>::result_type param2_type; typedef ret_type (*composited_type)(param1_type, param2_type); typedef typename replace_aux<R (*)(P1, P2), A, B, composited_type>::result_type result_type;};
[解决办法]
//TypeReplace4Templ.hxx#pragma oncetemplate<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;};