gpt4 book ai didi

c++ - 使用模板进行递归类型检查

转载 作者:行者123 更新时间:2023-11-30 03:44:33 25 4
gpt4 key购买 nike

我有几个类型检查模板:is_object来自 type_traitsisSupportedContainer实现方式如下:

template <class T>
struct isSupportedContainer
: public false_type {};

template <class T>
struct isSupportedContainer < list<T> >
: public true_type {};

/*other containers*/

我想进行递归检查 isSupported不仅将自身应用于容器类型,还应用于包含的类型。当前的实现:

// using std::__and_ and std::for from type_traits
template <class T>
struct isSupported
: public __and_ < __or_ < is_object<T>, isSupportedContainer<T> >,
isSupported <T> > {};

当我调用 isSupported < vector<int> >::value ,它会产生一堆编译错误(缩短):

In instantiation of 'struct std::__and_<...>, isSupportedContainer<std::vector<...> > >, isSupported<std::vector<...> > >':
required from 'struct isSupported<std::vector<int> >'
required from /*its call in main()*/
error: invalid use of incomplete type 'std::conditional<true, isSupported<std::vector<int> >, std::__or_<...>, isSupportedContainer<std::vector<...> > > >::type'
struct __and_<_B1, _B2>
^
In /*file containing isSupported and isSupportedContainer*/:
error: declaration of 'std::conditional<true, isSupported<std::vector<int> >, std::__or_<...> >::type'
struct isSupported
^
In function 'int main()':
error: 'value' is not a member of 'isSupported<std::vector<int> >'
cout << isSupported < vector<int> >::value;
^

那么,如何实现这样的检查呢?

例子:假设listvector作为支持类 vector<list<int>>也支持和vector<list<vector<string>>>不是

UPD:一个工作版本
UPD2:不,不工作

template <class T>
struct isSupported
: public isSupportedSimpleObject<T> {}; //is_object turned out to be a wrong thing

template <template<class> class T, class U>
struct isSupported < T<U> >
: public __and_ < isSupportedContainer<T<U>>,
isSupported <U> > {};

最佳答案

如果使用 enable_if 可能会简化整个计算在初始替换中。

#include <type_traits>
#include <list>
#include <vector>
#include <string>

template <class T>
struct isSupportedContainer : std::false_type {};

template <class T>
struct isSupportedContainer < std::list<T> > : std::true_type {};

template <class T>
struct isSupportedContainer < std::vector<T> > : std::true_type {};

template <class T, typename = void> // #1
struct isSupported : std::integral_constant<bool, std::is_object<T>::value> {};

template <class Cont> // #2
struct isSupported<Cont, typename std::enable_if<isSupportedContainer<Cont>::value>::type>
: isSupported<typename Cont::value_type> {};


int main() {
static_assert(isSupported<std::vector<int>>::value,"");
static_assert(isSupported<std::vector<std::list<int>>>::value,"");
static_assert(isSupported<std::string>::value,"");
static_assert(!isSupported<int&>::value,"");
return 0;
}

Live Demo

此技术(如果它确实是您所追求的)是基于 std::void_t 的原则被添加到 C++17

关键点如下:

  1. 主要模板定义接受两个类型参数。第一个被命名为T ,另一个未命名,默认类型为 void .此版本仅检查您的基本情况。
  2. 当您实例化模板时,编译器匹配主实例 isSupported<YourType, void> .
    现在编译器检查是否有与参数类型匹配的特化 <YourType, void> ,所以它会查看所提供的特化。 std::enable_if用于确定它的类型实际上是受支持的容器,如果是这样,它返回 void ,我们匹配最初推导的类型 <YourType, void> .因此编译器将特化作为更好的匹配,我们进行递归检查。
  3. 但是,如果提供的类型不是受支持的容器,std::enable_if没有type成员,然后 SFINAE 开始。替换失败,我们返回到我们在 (1) 中找到的基本情况,它进行基本检查。

关于c++ - 使用模板进行递归类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35390899/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com