From 7a1de2a43c69289ef3480633f191840702e88cfb Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Tue, 16 Jun 2026 09:09:18 -0500 Subject: [PATCH] COMP: Skip fpclassify for integral vnl_math classification predicates numeric_predicates::isfinite/isnan/isinf/isnormal forwarded std::isfinite(arg) etc. for every TArg. For integral TArg this instantiates the Windows UCRT integer template, where fpclassify() is an ambiguous call (error C2668) on some MSVC toolsets, so vnl_matrix/vnl_vector of an integer type fail to compile. Short-circuit integral arguments with if constexpr: an integer is always finite, never inf/NaN, and normal when non-zero. --- core/vnl/vnl_math.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/core/vnl/vnl_math.h b/core/vnl/vnl_math.h index 4c9d87b1bd..31e3c6a11a 100644 --- a/core/vnl/vnl_math.h +++ b/core/vnl/vnl_math.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef _MSC_VER # include @@ -179,29 +180,45 @@ namespace numeric_predicates { // Wrap the classification functions to guarantee a bool return type; // some standard libraries returned a signed integer from these. +// Integral arguments are short-circuited: an integer is always finite, never +// inf/NaN, and normal when non-zero. This also avoids an ambiguous fpclassify +// overload in older Windows SDK integer templates, where +// std::isfinite/isnan of an integer fails to compile (error C2668). template inline bool isinf(TArg arg) { - return bool(std::isinf(arg)); + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isinf(arg)); } template inline bool isnan(TArg arg) { - return bool(std::isnan(arg)); + if constexpr (std::is_integral_v) + return false; + else + return bool(std::isnan(arg)); } template inline bool isfinite(TArg arg) { - return bool(std::isfinite(arg)); + if constexpr (std::is_integral_v) + return true; + else + return bool(std::isfinite(arg)); } template inline bool isnormal(TArg arg) { - return bool(std::isnormal(arg)); + if constexpr (std::is_integral_v) + return arg != TArg(0); + else + return bool(std::isnormal(arg)); } } // namespace numeric_predicates