无法区分 enable_if 和 is_base_of 的模板专业化
Unable to discriminate template specialization with enable_if and is_base_of
我正在尝试将一些 运行 时间检查换成编译时间检查,以识别具有模板特化的对象的基础 class。
代码编译正常,但我无法弄清楚为什么 enable_if
语句总是无效或等于 void
,因为我总是登陆基本模板结构。
#include <iostream>
#include <type_traits>
using namespace std;
struct BaseOne {};
struct DerivedOne : BaseOne {};
struct BaseTwo {};
struct DerivedTwo : BaseTwo {};
struct Default {};
template<typename T, typename = void>
struct get_category_impl {
static constexpr int value = 0;
};
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseOne, T>::value, T>::type> {
static constexpr int value = 1;
};
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseTwo, T>::value, T>::type> {
static constexpr int value = 2;
};
template<typename T>
constexpr int get_category = get_category_impl<T>::value;
int main() {
cout << get_category<BaseOne> << "\n"; // prints 0
cout << get_category<DerivedOne> << "\n"; // prints 0
cout << get_category<BaseTwo> << "\n"; // prints 0
cout << get_category<DerivedTwo> << "\n"; // prints 0
cout << get_category<Default> << "\n"; // prints 0
}
不需要指定 enable_if
的第二个参数。如果您确实指定了它,它需要以某种方式解析为 void
。由于您已将第二个参数指定为 T
,因此这不起作用。
相反,只需这样做:
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseOne, T>::value>::type> {
// ^ No T
static constexpr int value = 1;
};
其他专业也是如此。
这里是 demo。
我正在尝试将一些 运行 时间检查换成编译时间检查,以识别具有模板特化的对象的基础 class。
代码编译正常,但我无法弄清楚为什么 enable_if
语句总是无效或等于 void
,因为我总是登陆基本模板结构。
#include <iostream>
#include <type_traits>
using namespace std;
struct BaseOne {};
struct DerivedOne : BaseOne {};
struct BaseTwo {};
struct DerivedTwo : BaseTwo {};
struct Default {};
template<typename T, typename = void>
struct get_category_impl {
static constexpr int value = 0;
};
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseOne, T>::value, T>::type> {
static constexpr int value = 1;
};
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseTwo, T>::value, T>::type> {
static constexpr int value = 2;
};
template<typename T>
constexpr int get_category = get_category_impl<T>::value;
int main() {
cout << get_category<BaseOne> << "\n"; // prints 0
cout << get_category<DerivedOne> << "\n"; // prints 0
cout << get_category<BaseTwo> << "\n"; // prints 0
cout << get_category<DerivedTwo> << "\n"; // prints 0
cout << get_category<Default> << "\n"; // prints 0
}
不需要指定 enable_if
的第二个参数。如果您确实指定了它,它需要以某种方式解析为 void
。由于您已将第二个参数指定为 T
,因此这不起作用。
相反,只需这样做:
template<typename T>
struct get_category_impl<T, typename enable_if<is_base_of<BaseOne, T>::value>::type> {
// ^ No T
static constexpr int value = 1;
};
其他专业也是如此。
这里是 demo。