Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何测试类型是否是具有非类型参数的模板的专用化?_C++_Templates_C++11_C++14 - Fatal编程技术网

C++ 如何测试类型是否是具有非类型参数的模板的专用化?

C++ 如何测试类型是否是具有非类型参数的模板的专用化?,c++,templates,c++11,c++14,C++,Templates,C++11,C++14,我想知道是否有任何解决方案可以确定一个类型是否是一个模板的特殊化,该模板接受非类型参数而不指定每个类型 例如,如果有这样一个类: template<typename T, std::size_t R> struct F {} 模板 结构F{} 现在,我使用了一个非常特殊的特性: template<template<typename, std::size_t> class TT, typename T> struct is_2 : std::false_ty

我想知道是否有任何解决方案可以确定一个类型是否是一个模板的特殊化,该模板接受非类型参数而不指定每个类型

例如,如果有这样一个类:

template<typename T, std::size_t R>
struct F {}
模板
结构F{}
现在,我使用了一个非常特殊的特性:

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 { };
模板
结构为_2:std::false_类型{};
模板
结构为_2:std::true_类型{};
并像
一样使用is_2::value
。然而,这是不实际的,因为如果您添加另一个模板参数,您必须编辑您的特征。此外,如果您有多个此类模板,则需要为每个模板编写一个traits


有什么办法使事情更实际吗?我会用C++14。我不是说用宏来减少代码量

非类型模板参数有点像红头发的继子

没有“任何模板参数是否匹配,类型是否匹配”


如果您可以修改
F
,则可以通过将常量包装为精简类型使其更加统一。因此:

template<typename T, class R>
struct F;

template<typename T, std::size_t R>
struct F<T, std::integral_constant<std::size_t, R>> {};
匹配一切

如果您对
F
的控制较少,则可以使用您的方法,或者编写元程序,将
模板
和该
模板
的实例提升到具有类型包装器的内容中

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> >;
这并不意味着更少的键入,但元化过程与
is
代码(或其他类似代码)相去甚远


我可能没有正确使用“lift”。

如果您可以修改
F
,并且没有您没有提到的其他限制,最简单的解决方案是添加一个唯一的基类:

#include <cstddef>
#include <type_traits>

struct unique_F_base {};

template<typename T, std::size_t R>
struct F : unique_F_base
{
};

template<typename T>
using is_F = std::is_base_of<unique_F_base,T>;

int main()
{
    static_assert( !is_F< int >::value, "Oops" );
    static_assert( is_F< F<int,42> >::value, "Oops" );
}
#包括
#包括
结构唯一的{u F_基{};
模板
结构F:唯一的F基
{
};
模板
使用is_F=std::is_base_of;
int main()
{
静态断言(!is_F::值,“Oops”);
静态断言(is_F:值,“Oops”);
}

您尝试过可变模板吗?是的,但是如果您使用typename…,它将只匹配类型,而不匹配bool或std::size\t。我需要一个任何。。。对于非类型模板参数,您可以使用
std::integral_constant
模拟
Any…
。您是否可以自由修改(即添加一些内容)到
F
?@DanielFrey在这种情况下,是的,我完全可以自由修改它。很好的解决方案,我没有想到。问题是,如果我有几个像F这样的类(但对于其他非类型参数,我必须为每个参数添加一个基类。@Baptistewich每个基类只有一行,您需要将其开销和复杂性与其他解决方案进行比较。添加基类并不性感,但它很简单、直接,而且斧头杀手在2年内维护您的代码不会有问题lem和它在一起:)
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>() ) ) > {};
#include <cstddef>
#include <type_traits>

struct unique_F_base {};

template<typename T, std::size_t R>
struct F : unique_F_base
{
};

template<typename T>
using is_F = std::is_base_of<unique_F_base,T>;

int main()
{
    static_assert( !is_F< int >::value, "Oops" );
    static_assert( is_F< F<int,42> >::value, "Oops" );
}