这是一个总体思路:
template <typename, typename> struct pattern;
template <typename T> struct pattern<T, T>
{
template <typename U> struct rebind
{
typedef U other;
};
};
template <typename A, typename B> struct pattern<A*, B>
{
template <typename U> struct rebind
{
typedef typename pattern<A, B>::template rebind<U>::other * other;
};
};
template <typename Haystack, typename Needle, typename New>
struct replace
{
typedef typename pattern<Haystack, Needle>::template rebind<New>::other type;
};
Test:
#include <demangle.hpp>
#include <iostream>
int main()
{
typedef replace<void, void, int>::type T1;
typedef replace<void*, void, int>::type T2;
std::cout << demangle<T1>() << std::endl;
std::cout << demangle<T2>() << std::endl;
}
Prints:
int
int*
Edit:这是一个更完整的集合:
template <typename, typename> struct pattern;
template <typename, typename> struct pattern_aux;
template <typename A, typename B> struct pattern_aux
{
template <typename U> struct rebind
{
typedef typename pattern<A, B>::template rebind<U>::other other;
};
};
template <typename A, typename B, unsigned int N> struct pattern_aux<A[N], B>
{
template <typename U> struct rebind
{
typedef typename pattern<A, B>::template rebind<U>::other other[N];
};
};
template <typename A, typename B> struct pattern
{
template <typename U> struct rebind
{
typedef typename pattern_aux<A, B>::template rebind<U>::other * other;
};
};
template <typename T> struct pattern<T, T>
{
template <typename U> struct rebind
{
typedef U other;
};
};
template <typename A, typename B> struct pattern<A*, B>
{
template <typename U> struct rebind
{
typedef typename pattern<A, B>::template rebind<U>::other * other;
};
};
template <typename A, typename B> struct pattern<A const, B>
{
template <typename U> struct rebind
{
typedef typename pattern_aux<A, B>::template rebind<U>::other const other;
};
};
template <typename A, typename B> struct pattern<A volatile, B>
{
template <typename U> struct rebind
{
typedef typename pattern_aux<A, B>::template rebind<U>::other volatile other;
};
};
template <typename A, typename B> struct pattern<A const volatile, B>
{
template <typename U> struct rebind
{
typedef typename pattern_aux<A, B>::template rebind<U>::other const volatile other;
};
};
template <typename Haystack, typename Needle, typename New>
struct replace
{
typedef typename pattern<Haystack, Needle>::template rebind<New>::other type;
};