Sur*_*K S 3 c++ templates type-traits c++20 c++-templates
我正在使用 C++20。我能够检查类型是否是某种向量/双端队列/列表,如下所示:
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>>);
Run Code Online (Sandbox Code Playgroud)
(我想知道在 C++20 中是否有更好的方法来做到这一点,现在我们有了requires表达式等。)
但是,现在我想要的是is_listish接受从向量/列表/双端队列派生的类。例如:
struct MyVec : public std::vector<int> { };
static_assert(is_listish<MyVec>); //This should be true
Run Code Online (Sandbox Code Playgroud)
我不确定这是否可能。这是我尝试过的:
template <typename B, typename D>
requires std::is_base_of_v<B, D>
struct is_listish_trait<D> {
static constexpr bool value = 1;
};
Run Code Online (Sandbox Code Playgroud)
然而,编译器抱怨它无法推导出 B(这是可以理解的)。
怎样才能做到这一点呢?
使用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); }
;
Run Code Online (Sandbox Code Playgroud)