我正在使用 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(这是可以理解的)。
如何才能做到这一点?
警告:从析构函数既不是虚拟函数也不是受保护函数的类派生是一个“坏主意”。因此对于标准容器不应该考虑这一点。然而,这个答案可以适用于析构函数是虚拟的(或受保护的)的自定义容器。
现在我想要的是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> {
static constexpr bool value = 1;
};
列表和双端队列也类似。