如何测试类型是否是具有非类型参数的模板的特殊化?
我想知道是否有任何解决方案来找到一个类型是否是一个模板的特殊化,它接受非类型的参数而不指定每个类型?
I was wondering if there was any solution to find if a type was a specialization of a template that takes non-type parameters without specifying every type ?
,如果有这样的类:
template<typename T, std::size_t R>
struct F {}
现在,我使用了一个非常特殊的特性: / p>
For now, I'm using a very specialized traits:
template<template<typename, std::size_t> class TT, typename T>
struct is_2 : std::false_type { };
template<template<typename, std::size_t> class TT, typename V1, std::size_t R>
struct is_2<TT, TT<V1, R>> : std::true_type { };
并像 is_2< F,T> :: value
。但是,这不现实,因为如果添加另一个模板参数,您必须编辑您的特性。此外,如果你有几个这样的模板,你需要写一个traits为每个。
and used like is_2<F, T>::value
. However, this is not practical since, if you add another template parameter, you have to edit your traits. Moreover, if you have several templates of this kind, you need to write a traits for each of them.
有什么办法让事情更实用吗?我可以使用C ++ 14。我不是说使用宏来减少代码量。
Is there any way to make something more practical ? I can use C++14. And I don't mean using a macro to reduce the code amount.
非类型模板参数是一个红色的小步。
Non-type template parameters are a bit of a red headed stepchild.
没有任何模板参数匹配,类型与否。
There is no "any template parameter is matched, type or not".
如果您可以修改 F
,你通过在稀薄类型中包装你的常量使它更一致。所以:
If you can modify F
, you make it more uniform by wrapping your constants in thin types. So:
template<typename T, class R>
struct F;
template<typename T, std::size_t R>
struct F<T, std::integral_constant<std::size_t, R>> {};
现在像的元程序是
template<template<class...>class Template, class T>
struct is_instantiation : std::false_type {};
template<template<class...>class Template, class... Ts>
struct is_instantiation<Template, Template<Ts...>> : std::true_type {};
匹配所有内容。
对 F
更少的控制,你可以使用你的方法,或者写一个元程序来提升模板
模板
转换为包含类型封装的内容。
If you have less control over F
, you can either use your approach, or write metaprogram that hoists both a template
and an instance of that template
into something with type wrappers.
struct meta_F {
template<class T, std::size_t R>using raw_apply=F<T,R>;
template<class T, class R>using apply=raw_apply<T,R::value_type>;
};
template<class meta_Template, class... Args>
struct type_lifted_template {};
template<class T, std::size_t R>
struct type_lifted_template< meta_F, T, std::integral_constant<std::size_t, R> > {
using result = meta_F::template raw_apply<T, R>;
};
template<class T, std::size_t R>
auto type_lift_instance( F<T,R> )
-> type_lifted_template< meta_F, T, std::integral_constant<std::size_t, R> >;
现在, type_lift_instance
类型,并且一些 decltype
magic可以用于提取不同类型的 type_lifted_template
专用化。
Now, type_lift_instance
can be specialized for multiple types, and some decltype
magic could be used to extract the type_lifted_template
specialization for different types.
这些都很粗糙。你最好是,如果你在模板上进行大量的元程序设计,只是让你的模板采用统一的类型参数,而不是搞砸这个东西。
All of this is pretty rough. You'd be best, if you are doing lots of meta programming on templates, to just have your templates take uniform type parameters, instead of messing around with this stuff.
template<class meta_F, class C>
struct meta_template_is_lifted : std::false_type {};
template<class meta_F, class...Ts>
struct meta_template_is_lifted<meta_F, type_lifted_template< meta_F, Ts... >> : std::true_type {};
template<class meta_F, class C>
struct meta_template_is : meta_template_is_lifted< meta_F, decltype(type_lift_instance( std::declval<C>() ) ) > {};
这不是很少打字,但元组化远离是
代码(或其他类似的代码)。
this isn't much less typing, but the metafication goes on far away from the is
code (or other similar code).
我可能使用不正确的电梯。
I'm probably using "lift" incorrectly.