bas*_*eln 3 c++ templates c++14
鉴于代码:
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> { ... };
Run Code Online (Sandbox Code Playgroud)
我如何实现一个特征,is_cat<T>以便
is_cat<Cat<int, float>>,is_cat<Bengal<double>>,is_cat<Persian<std::string>>和is_cat<Siberian>是std::true_typeis_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*>()));
Run Code Online (Sandbox Code Playgroud)
对于一些这是一个Cat<T,U>,Cat<T,U>*是一个更好的比赛比...其他任何东西,它不是在所有的比赛。
如果您还想 match 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&>()));
Run Code Online (Sandbox Code Playgroud)