c++ 如何检查类型是否从vector / list / deque派生?

aamkag61  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(79)

我使用C++20。我可以检查类型是否是somevector / deque / list,如下所示:

template <typename N> struct is_listish_trait {
  static constexpr bool value = 0;
};

/* These are listish specializations */
template <typename N, typename A> struct is_listish_trait<std::vector<N, A>> {
  static constexpr bool value = 1;
};

template <typename N, typename A> struct is_listish_trait<std::list<N, A>> {
  static constexpr bool value = 1;
};

template <typename N, typename A> struct is_listish_trait<std::deque<N, A>> {
  static constexpr bool value = 1;
};

template <typename T>
static constexpr bool is_listish = is_listish_trait<T>::value;

static_assert(!is_listish<int>);
static_assert(is_listish<std::vector<int>>);

字符串
(我想知道在C++20中是否有更好的方法来做到这一点,现在我们有了requires表达式等。
然而,现在我想要的是is_listish接受从vectors / lists / deques派生的类。例如:

struct MyVec : public std::vector<int> { };
static_assert(is_listish<MyVec>); //This should be true


我不确定这是否可行。这是我试过的:

template <typename B, typename D>
  requires std::is_base_of_v<B, D>
struct is_listish_trait<D> {
  static constexpr bool value = 1;
};


然而,编译器抱怨说它不能推导出B(这是可以理解的)。
怎么能这样呢?

nuypyhwy

nuypyhwy1#

使用requires,您可以:

template <typename T>
concept is_listish =
       requires(T t) { []<typename U, typename A>(std::vector<U, A>&){}(t); }
    or requires(T t) { []<typename U, typename A>(std::list<U, A>&){}(t); }
    or requires(T t) { []<typename U, typename A>(std::deque<U, A>&){}(t); }
    ;

字符串
Demo

mf98qq94

mf98qq942#

  • 警告:*从一个析构函数既不是virtual也不是protected的类中派生是一个坏主意。因此,对于标准容器,不应该考虑这一点。但是,这个答案可以适用于析构函数是virtual(或protected)的自定义容器。

现在我想要的是is_listish接受从vectors / lists / deques派生的类。
你可以简单地在requires子句中明确说明这一点。你要求所讨论的类型有一个基类std::vector。你只需要指定合适的值和分配器类型。幸运的是,std::vector将它们作为成员类型提供。(如果这些成员类型不存在,那么这种特殊化不应该也不会适用。)* 如果一个类有多个提供这些成员类型的基类,这种方法将失败。*

template <typename N>
  // This partial specialization applies only to classes derived from std::vector.
  requires std::is_base_of_v<
    std::vector<typename N::value_type, typename N::allocator_type>,
    N>
struct is_listish_trait<N> : std::true_type {};

字符串
类似的还有list和deque。

相关问题