给定代码:
template<typename T, typename Other = SomeDefault>
struct Cat { ... };
template<typename T>
struct Bengal : Cat<T> { ... };
template<typename T>
struct Persian : Cat<T, Something> { ... };
struct Siberian : Cat<int> { ... };
我如何实现特征 is_cat<T>
这样
-
is_cat<Cat<int, float>>
,is_cat<Bengal<double>>
,is_cat<Persian<std::string>>
和is_cat<Siberian>
是std::true_type
-
is_cat<double>
(以及其他不相关的类型)是std::false_type
我认为std::is_base_of
是正确的方向,但我不知道如何让它与基类的未知类型参数一起工作。
最佳答案
std::is_base_of
在这里没有帮助,它只检查一个具体的基类是否是一个基类。但我们不是在寻找具体的基础,而是在寻找基类模板。为此,我们可以利用重载决议:
std::false_type is_cat_impl(...);
template <typename T, typename U>
std::true_type is_cat_impl(Cat<T,U>*);
template <typename T>
using is_cat = decltype(is_cat_impl(std::declval<T*>()));
对于 Cat<T,U>
的东西, Cat<T,U>*
是比 ...
更好的匹配至于别的,那根本就不是一场比赛。
如果你还想匹配Siberian const&
,然后,正如 Oliv 所建议的,最好使用引用而不是指针:
std::false_type is_cat_impl(...);
template <typename T, typename U>
std::true_type is_cat_impl(Cat<T,U> const volatile&);
template <typename T>
using is_cat = decltype(is_cat_impl(std::declval<T&>()));
关于c++ - 使用基类模板检测 is_base_of,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51910808/