是否可以编写一个元函数,给定具有多个特定类型template<class> class Decor
的类型的类型,返回类型而不出现类Decorator
的类型。
一个例子是转换以下类型
A<Decor<T<B<A<Decor<C>>>>>>
成
A<T<B<A<C>>>>
我们假设最终类型的结构确实是一个正确的类型,但我们不假设输入类型的结构。情况可能是用于构造输入类型的某些类型具有template<class...> class
形式或任何其他类型类。
答案 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...>; }
如果模板可能包含值或模板模板参数,则需要更多专业化。