c++ - 带有 numeric_limits 的 SFINAE::max() 在 MSVC2017 上
问题描述
以下代码:
template <typename T, typename U>
typename std::enable_if<
std::numeric_limits<T>::max() == std::numeric_limits<U>::max(),
bool>::type
same_max() {
return true;
}
template <typename T, typename U>
typename std::enable_if<
std::numeric_limits<T>::max() != std::numeric_limits<U>::max(),
bool>::type
same_max() {
return false;
}
无法在 MSVC2017 上编译(在 gcc/clang 上正常),出现以下错误:
error C2995: 'std::enable_if<,bool>::type same_max(void)': function template has already been defined
这是我的 SFINAE 的问题,还是 MSVC 中的错误?
注意:使用std::numeric_limits<T>::is_signed
(or std::is_signed<T>::value
) 而不是std::numeric_limits<T>::max()
编译得很好:
template <typename T, typename U>
typename std::enable_if<
std::is_signed<T>::value == std::is_signed<U>::value,
bool>::type
same_signedness() {
return true;
}
template <typename T, typename U>
typename std::enable_if<
std::is_signed<T>::value != std::is_signed<U>::value,
bool>::type
same_signedness() {
return false;
}
解决方案
这绝对看起来像是编译器中的错误。它不接受 SFINAE 中的成员函数(请注意,问题中的代码不仅对于min()
/失败max()
,而且对于任何类似epsilon()
or的成员函数都失败lowest()
),但它确实接受成员常量。您可以使用以下简单的解决方法和额外的间接级别struct
(如果仅限于 C++11):
template<typename T>
struct get_max {
static constexpr T value = std::numeric_limits<T>::max();
};
template <typename T, typename U>
typename std::enable_if<get_max<T>::value == get_max<U>::value, bool>::type
same_max() {
return true;
}
template <typename T, typename U>
typename std::enable_if<get_max<T>::value != get_max<U>::value, bool>::type
same_max() {
return false;
}
或变量模板(C++14 起):
template<typename T>
inline constexpr T get_max_v = std::numeric_limits<T>::max();
template <typename T, typename U>
std::enable_if_t<get_max_v<T> == get_max_v<U>, bool>
same_max() {
return true;
}
template <typename T, typename U>
std::enable_if_t<get_max_v<T> != get_max_v<U>, bool>
same_max() {
return false;
}
min
为避免在某些头文件(如 )中定义的/max
宏的潜在问题windef.h
,函数名可以用括号括起来:
... = (std::numeric_limits<T>::max)();
推荐阅读
- junit - JUnit 显示错误 java.lang.NoClassDefFoundError: org/junit/runner/manipulation/Filter
- android - 即使清单具有主要活动,Android中也缺少应用程序图标和名称
- maven - Gradle 依赖范围
- scala - Scala:用 ReaderT 和 Option 编写理解
- python-3.x - Kafka-Python 如何手动提交?
- ios - 如何自动调整 ViewController 根视图的大小以适应其内容?
- amazon-web-services - 跨 VPC 连接 RDS,无需 Peering
- java - 如何从某些 Firestore 集合中存在的 recyclerview 中排除项目
- sql - 如何将查询结果转换为字符串并将其插入表行
- laravel - 无法更新 Laravel 数据库(模型、视图、控制器)