2017-08-15 126 views
1

是否可以编写一个元函数,如果某种类型包含多个特定类型的事件template<class> class Decor,则返回该类型,但不显示类Decorator删除嵌套类型中的所有包装类型

的一个例子是以下类型 A<Decor<T<B<A<Decor<C>>>>>> 转换成 A<T<B<A<C>>>>

我们假设最终类型的结构的确是一个正确的类型,但我们不输入型的结构假设任何事情。可能会出现这样的情况:用于构建输入类型的某些类型的格式为template<class...> class或任何其他类型的类。

回答

0
template <class T> 
struct RemDec 
{ using type = T; }; 
template <class T> 
struct RemDec<Decor<T>> 
{ using type = T; }; 
template <class T> 
struct RemDec<T&> 
{ using type = typename RemDec<T>::type&; }; 
template <class T> 
struct RemDec<T&&> 
{ using type = typename RemDec<T>::type&&; }; 
template <class T> 
struct RemDec<const T> 
{ using type = typename RemDec<T>::type const; }; 
template <class T> 
struct RemDec<volatile T> 
{ using type = typename RemDec<T>::type volatile; }; 
template <template <typename...> class TT, class... Ts> 
struct RemDec<TT<Ts...>> 
{ using type = TT<typename RemDec<Ts>::type...>; } 

如果您的模板可能具有值或模板模板参数,您将需要更多的专业化。

+0

你的确有一个很好的观点。 – Lezkus

1

您可以使用类模板,像这样一对夫妇专门化:

template<typename T> 
struct RemDec { 
    using type = T; 
}; 

template<template<typename...> class C, typename... T> 
struct RemDec<C<T...>> { 
    using type = C<typename RemDec<T>::type...>; 
}; 

template<typename T> 
struct RemDec<Decorator<T>> { 
    using type = typename RemDec<T>::type; 
}; 

类模板有助于停止迭代在你的类型的链条。
第一个专业记忆一个类模板,并帮助清理遗留物。
最后一个专业化将删除检测到的Decorator,并继续分析剩下的内容。


它遵循最小,工作示例:

#include<type_traits> 

template<typename> 
struct Decorator {}; 

template<typename...> 
struct S {}; 

template<typename T> 
struct RemDec { 
    using type = T; 
}; 

template<template<typename...> class C, typename... T> 
struct RemDec<C<T...>> { 
    using type = C<typename RemDec<T>::type...>; 
}; 

template<typename T> 
struct RemDec<Decorator<T>> { 
    using type = typename RemDec<T>::type; 
}; 

int main() { 
    static_assert(std::is_same< 
     typename RemDec<S<Decorator<S<S<Decorator<S<int>>>>>, Decorator<S<double>>>>::type, 
     S<S<S<S<int>>>, S<double>> 
    >::value, "!"); 
} 

正如你可以运行它看,任何实例Decorator是从原始类型删除。

+0

上帝,你是对的。我几乎实现了这一点,但我错过了一些东西,我认为你不能做这种类型的匹配。 正如我所指出的那样,该类在其模板参数中可以是可变的,但泛化是微不足道的。非常感谢! – Lezkus

+0

@Lezkus错过了可变的评论。请给我几分钟的时间来整合答案。 – skypjack

+1

@Lezkus完成。现在代码是_variadic-oriented_。 ;-) – skypjack