具有常量值的任何模板化类型的类型特征

Type trait for any templated types with constant values

本文关键字:类型 特征 任何模 常量      更新时间:2023-10-16

我目前正在制作一个代码,该代码需要针对任何具有模板的类型进行特定的实现,因此我正在尝试编写适用于任何模板化类型的类型特征。

现在,我有这个:

template<class T> 
struct TIsTemplated { enum { Value = 0 }; };
template<template<typename, typename...> class T, typename First, typename... Values> 
struct TIsTemplated<T<First, Values...>> { enum { Value = 1 }; };

这适用于模板化类型,例如

template<typename T>
struct X { };

但是,一旦存在具有常量值的类型,它就会失败:

template<typename T, int i = 10>
struct Y {};

我发现我可以做一个这样的类型:

template<int A, template<typename, int> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; };

但是,这只有在我预先知道我将有一个需要int的类型时才有效。我试图概括这一点:

template<typename C>
template<C A, template<typename, C> class T, typename First> 
struct TIsTemplated<T<First,A>> { enum { Value = 1 }; };

但即使这编译正确,TIsTemplated对于类型 Y 仍然是错误的。有没有办法在不必知道常量类型的情况下实现这一点?

template<class...>struct types{using type=types;};

是类型的捆绑包。

template<class Scalar, class T>
struct is_template_with_scalar : std::false_type {};
template<class Scalar, template<class,Scalar>class Z, class U, Scalar s>
struct is_template_with_scalar<Scalar, Z<U,s>> : std::true_type {};

测试是否给定Scalar类型,该类型是否T与模式template<class, Scalar>匹配。

然后我们把它卷曲一下:

template<class Scalar>
struct scalar_test {
  template<class T>
  using result=is_template_with_scalar<Scalar, T>;
};

这需要一堆布尔类型,并评估它们的逻辑或:

template<class...Ts>
struct or_types : std::false_type {};
template<class T0, class...Ts>
struct or_types<T0, Ts...> : std::integral_constant<bool, T0{} || or_types<Ts...>{} >
{};

passes_any采用类型列表,以及采用类型的元测试。 它生成一个测试,说明是否有任何测试通过:

template<class List, template<class>class Test>
struct passes_any {};
template<class...Ts, template<class>class Test>
struct passes_any<types<Ts...>, Test> {
  template<class U>
  using result=or_types< typename Test<Ts>::template result<U>... >;
};

现在,我们从:

using scalars_supported = types<int, char, std::size_t, unsigned>; // etc

我们得到了一个测试:

template<class T>
using is_scalar_template = 
  typename passes_any<scalars_supported,scalar_test>::template result<T>;

给定类型T是模板的实例,其模式<class, Scalar>适用于scalars_supported列表中的任何Scalar,则该类型为真实类型。

现场示例