如何检查类型是否源自向量/列表/双端队列?

问题描述 投票:0回答:2

我正在使用 C++20。 我能够检查类型是否为some向量/双端队列/列表,如下所示:

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
接受从向量/列表/双端队列派生的类。例如:

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(这是可以理解的)。

如何才能做到这一点?

c++ templates c++20 type-traits c++-templates
2个回答
3
投票

警告:从析构函数既不是虚拟函数也不是受保护函数的类派生是一个“坏主意”。因此对于标准容器不应该考虑这一点。然而,这个答案可以适用于析构函数是虚拟的(或受保护的)的自定义容器。

现在我想要的是
is_listish

接受从向量/列表/双端队列派生的类。


您可以在
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 {};

列表和双端队列也类似。


1
投票
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); }
    ;

演示

© www.soinside.com 2019 - 2024. All rights reserved.