删除嵌套类型中的所有包装器类型

时间:2017-08-15 17:11:24

标签: c++ metaprogramming

是否可以编写一个元函数,给定具有多个特定类型template<class> class Decor的类型的类型,返回类型而不出现类Decorator的类型。

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

我们假设最终类型的结构确实是一个正确的类型,但我们不假设输入类型的结构。情况可能是用于构造输入类型的某些类型具有template<class...> class形式或任何其他类型类。

2 个答案:

答案 0 :(得分: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的任何实例都将从原始类型中删除。

答案 1 :(得分: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...>; }

如果模板可能包含值或模板模板参数,则需要更多专业化。