虽然有点晚了,但我想提供一种以上内容的变体。
template < template <typename...> class Base,typename Derived>
struct is_base_of_template
{
template<typename... Ts> static constexpr std::variant<Ts...> is_callable( Base<Ts...>* );
template <typename T> using is_callable_t = decltype( is_callable( std::declval<T*>() ) );
static inline constexpr bool value = std::experimental::is_detected_v<is_callable_t,Derived>;
using type = std::experimental::detected_or_t<void,is_callable_t,Derived>;
};
template < template <typename...> class Base,typename Derived>
using is_base_of_template_t = typename is_base_of_template<Base,Derived>::type;
template < template <typename...> class Base,typename Derived>
inline constexpr bool is_base_of_template_v = is_base_of_template<Base,Derived>::value;
这里使用了提议中的is_detected机制,我认为这使测试的意图更清晰。然而,现在我可以同时获取基类实例化的类型,这对我很有用。所以我可以写成:
template <typename T, typename U> struct Foo { };
struct Bar : Foo<int,std::string> { };
static_assert( is_base_of_template_v<Foo,Bar> );
static_assert( std::is_same_v<std::variant<int,std::string>,is_base_of_template_t<Foo,Bar>> );
my_is_base_of<A, B<int>, char>
这样的用法合理吗? - TartanLlama