Minimal, complete, verifiable example on godbolt
I have a concept Trait_AActuallyBTemplate<A, B>
to check if type A
is an instance of template B
, and it works.
How could I create a new concept to check if A
inherits from B<...something...>
?
#include <vector>
#include <iostream>
namespace hid{
template <typename T,template<typename... Ty> typename B>
struct is_mytype : std::false_type { };
template <typename... A,template<typename... Ty> typename B>
struct is_mytype<B<A...> ,B> : std::true_type { };
};
template <typename T,template<typename... Ty> typename B>
concept Trait_AActuallyBTemplate = hid::is_mytype<T,B>::value;
//vvv need modifying here
template <typename T,template<typename... Ty> typename B>
concept Trait_AInheritFromBTemplate = hid::is_mytype<T,B>::value;
//^^^ need modifying here
int main() {
static_assert(Trait_AActuallyBTemplate<std::vector<int>,std::vector>,"hehe1");
static_assert(!Trait_AActuallyBTemplate<int,std::vector>,"hehe2");
struct MyVector : public std::vector<int> {};
static_assert(Trait_AInheritFromBTemplate<MyVector,std::vector>,"hehe3");
//^^^ Assert only fails here. (It should work. I am sad.)
}
You check this by attempting to call a dummy (templated) function accepting a pointer to the base. This will reject inaccessible or ambiguous bases, but this is usually desirable.
namespace detail
{
template <template <typename...> typename T, typename ...P>
constexpr void foo(const T<P...> *) {}
}
template <typename T, template <typename...> typename U>
concept InheritsFromTemplate = requires(T *t){detail::foo<U>(t);};
template <typename ...P> struct A {};
struct B : A<int, float> {};
struct C {};
struct D : virtual A<int, float> {};
struct E : private A<int, float> {};
struct F : A<int, float>, A<double> {};
static_assert(InheritsFromTemplate<A<int, float>, A>); // Exact match.
static_assert(InheritsFromTemplate<B, A>); // Inherits.
static_assert(!InheritsFromTemplate<C, A>); // Doesn't inherit.
static_assert(InheritsFromTemplate<D, A>); // Virtual inheritance is ok.
static_assert(!InheritsFromTemplate<E, A>); // Inaccessible base is rejected.
static_assert(!InheritsFromTemplate<F, A>); // Ambiguous base is rejected.