// 总的来说,模板的特化能继承模板的不特化
#include "TypeList.cpp"
#include <type_traits>
template <TL In , template <typename >class P, TL OUT = TypeList<> >
struct Filter : OUT {} ;
template <template <typename >class P, TL Out, typename H, typename ... Ts>
struct Filter <TypeList<H, Ts...>, P, Out> :
Filter<TypeList<Ts...>, P,Out>
{};
// struct Filter <TypeList<H, H2,Ts...>, P, Out> :
// Filter<TypeList<H2,Ts...>, P, Out>
// {};
// 可以编译通过
// 下面这个改为单独加一个H3,就不行了error了
// template <template <typename >class P, TL Out, typename H, typename H2,typename H3, typename ... Ts>
// struct Filter <TypeList<H, H2,Ts...>, P, Out> :
// Filter<TypeList<H3,Ts...>, P, Out>
// {};
// struct Filter <TypeList<H, Ts...>, P, Out> :
// Filter<TypeList<H,Ts...>, P, Out>
// {};
// error: recursive type
// struct Filter <TypeList<Ts...>, P, Out> :
// Filter<TypeList<H, Ts...>, P, Out>
// {};
// error: template parameters not deducible in partial specialization:
int main(){}
// template <template <typename >class P, TL Out, typename H, typename ... Ts>
// struct Filter <TypeList<Ts...>, P, Out> :
// Filter<TypeList<Ts...>, P, typename Out:: template append<H> >
// {};
// error , 这样也不行
一句话总结:继承自己时,子类约束更多,且父类约束能包含子类约束的情况。
且约束不区分顺序,且全特化父类能包含一切子类。
PS:自己总结悟的,还望多多交流。
附上:cppinsights。
源代码:
#include <cstddef>
template <typename ...Ts>
class TypeList
{
public:
using type = TypeList;
struct IsTypeList { } ;
static constexpr size_t size = sizeof...(Ts);
template <typename ...T>
using append = TypeList<Ts..., T...>;
template <typename ...T>
using prepend = TypeList<T..., Ts...>;
template <template<typename...>class T>
using to = T<Ts...>;
};
template <typename TypeList >
concept TL = requires {
typename TypeList::IsTypeList;
typename TypeList::type;
};
using LongList = TypeList<long, char,int>;
#include <type_traits>
template <TL In , template <typename >class P, TL OUT = TypeList<> >
struct Filter : OUT {} ;
template <template <typename >class P, TL Out, typename H, typename ... Ts>
struct Filter <TypeList<H, Ts...>, P, Out> : // 这个继承自己的操作
std::conditional_t < P<H>::value,
Filter<TypeList<Ts...>, P, typename Out ::template append<H> >, // 前面要加typename
Filter<TypeList<Ts...>, P, Out>
>
{};
template <typename T>
using sizeless4 = std::integral_constant<bool, (sizeof(T) < 4 )>;
template <TL In , template <typename >class P, TL OUT = TypeList<> >
using Filter_t = typename Filter<In, P, OUT>::type; // 思考为什么要加_t ,
static_assert(std::is_same_v< // std::static_assert 不行
Filter_t<LongList, sizeless4>
,TypeList<char>
>);
int main(){}
cppinsights 编译后
#include <cstddef>
template<typename ... Ts>
class TypeList
{
public:
using type = TypeList<Ts...>;
struct IsTypeList
{
};
inline static constexpr const size_t size = sizeof...(Ts);
template<typename ... T>
using append = TypeList<Ts..., T...>;
template<typename ... T>
using prepend = TypeList<T..., Ts...>;
template<template <typename> typename T>
using to = T<Ts...>;
};
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<long, char, int>
{
public:
using type = TypeList<long, char, int>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<long, char, int, T...>;
template<typename ... T>
using prepend = TypeList<T..., long, char, int>;
template<template <typename> typename T>
using to = T<long, char, int>;
};
#endif
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<>
{
public:
using type = TypeList<>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<T...>;
template<typename ... T>
using prepend = TypeList<T...>;
template<template <typename> typename T>
using to = T<>;
};
#endif
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<char, int>
{
public:
using type = TypeList<char, int>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<char, int, T...>;
template<typename ... T>
using prepend = TypeList<T..., char, int>;
template<template <typename> typename T>
using to = T<char, int>;
};
#endif
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<long>
{
public:
using type = TypeList<long>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<long, T...>;
template<typename ... T>
using prepend = TypeList<T..., long>;
template<template <typename> typename T>
using to = T<long>;
};
#endif
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<int>
{
public:
using type = TypeList<int>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<int, T...>;
template<typename ... T>
using prepend = TypeList<T..., int>;
template<template <typename> typename T>
using to = T<int>;
};
#endif
/* First instantiated from: insights.cpp:24 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class TypeList<char>
{
public:
using type = TypeList<char>;
struct IsTypeList;
static constexpr const size_t size;
template<typename ... T>
using append = TypeList<char, T...>;
template<typename ... T>
using prepend = TypeList<T..., char>;
template<template <typename> typename T>
using to = T<char>;
};
#endif
template<typename TypeList>
concept TL = requires{
typename TypeList::IsTypeList;
typename TypeList::type;
};
using LongList = TypeList<long, char, int>;
#include <type_traits>
template<TL In, template <typename> typename P, TL OUT = TypeList<>>
struct Filter : public OUT
{
};
/* First instantiated from: insights.cpp:37 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Filter<TypeList<char, int>, sizeless4, TypeList<> > : public Filter<TypeList<int>, sizeless4, TypeList<char> >
{
};
#endif
/* First instantiated from: insights.cpp:37 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Filter<TypeList<int>, sizeless4, TypeList<char> > : public Filter<TypeList<>, sizeless4, TypeList<char> >
{
};
#endif
/* First instantiated from: insights.cpp:37 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Filter<TypeList<>, sizeless4, TypeList<char> > : public TypeList<char>
{
};
#endif
/* First instantiated from: insights.cpp:47 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Filter<TypeList<long, char, int>, sizeless4, TypeList<> > : public Filter<TypeList<char, int>, sizeless4, TypeList<> >
{
};
#endif
template<template <typename> typename P, TL Out, typename H, typename ... Ts>
struct Filter<TypeList<H, Ts...>, P, Out> : public std::conditional_t<P<H>::value, Filter<TypeList<Ts...>, P, typename Out::template append<H> >, Filter<TypeList<Ts...>, P, Out> >
{
};
template <typename T>
using sizeless4 = std::integral_constant<bool, (sizeof(T) < 4 )>;
template <TL In , template <typename >class P, TL OUT = TypeList<> >
using Filter_t = typename Filter<In, P, OUT>::type; // 思考为什么要加_t ,
/* PASSED: static_assert(std::is_same_v<TypeList<char>, TypeList<char> >); */
int main()
{
return 0;
}