Visual Microsoft C++ 编译器是否足够聪明,知道 std::isnan 不是在我的代码中调用的整数类型?



这与我之前的文章';fpcategory';:对重载函数的模糊调用

我试图更正产生错误的代码。原始代码如下所示。

struct alignas(1) wrapped_int8 {
using underlying = int8_t;
int8_t value;
// some other function definitions
};
template <typename T>
void func(T val) {
auto mask = std::isnan(val);
}
int main(int argc, char const *argv[])
{  
func<wrapped_int8::underlying>(4);
}

由于fpclassify重载模糊性问题以及microsoft内部版本缺少对fpclassify的积分重载,它无法使用microsoft编译器进行编译。

所以我把func改成:

template <typename T>
void func(T val) {
auto mask = std::is_integral<T>::value ? false : std::isnan(val);
}

但这仍然给出了相同的错误。根据我的代码逻辑,如果T是积分类型,我们就不应该调用std::isnan,所以fpclassify应该不会有问题,但编译器是否足够聪明,知道不会在积分类型上调用std::isnan?如果是这样,为什么它仍然会产生这个错误?如果没有,我该如何解决此问题?

您可以使用if constexpr放弃对std::isnan(val)的调用。

template <typename T>
void func(T val) {
auto mask = [&] {
if constexpr (std::is_integral_v<T>)
return false;
else
return std::isnan(val);
}();
}

C++14版本

template<class T>
constexpr typename std::enable_if<std::is_integral_v<T>, bool>::type 
mask_impl(T val) {
return false;
}
template<class T>
constexpr typename std::enable_if<std::is_floating_point_v<T>, bool>::type 
mask_impl(T val) {
return std::isnan(val);
}
template <typename T>
void func(T val) {
auto mask = mask_impl(val);
}

如果允许C++17

template <typename T>
void func(T val) {
auto mask = false;
if constexpr (!std::is_integral<T>::value)
mask = std::isnan(val);
}

如果是C++14或更早的

template <typename T>
void func(T val) {
auto mask = std::isnan(val);
}
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void func(T val) {
auto mask = false;
}

你也可以破解std::isnanint8_t

namespace std {
bool isnan(int8_t val) noexcept { return false; }
}

相关内容

最新更新