std::is_floating_point 是标准库中定义在 <type_traits> 头文件里的类型特征模板,用于编译期判断类型是否为浮点类型(如 float、double、long double 等),返回 std::integral_constant<bool, value>,支持 if constexpr、SFINAE 和 requires 约束。

std::is_floating_point 是什么类型特征
std::is_floating_point 是标准库中定义在 <type_traits> 头文件里的一个变量模板(C++17 起)或类模板(C++11/14),用于在编译期判断某个类型是否为浮点类型(即 float、double、long double,以及可能的扩展浮点类型如 __float128,取决于实现)。
它不关心值,只看类型本身;返回的是一个 std::integral_constant<bool, value>,所以能直接用在 if constexpr、SFINAE 或 requires 约束里。
怎么在 if constexpr 中做分支选择
C++17 起最常用、最直观的用法就是在模板函数里配合 if constexpr 做编译期分发,避免为非浮点类型实例化不合法代码(比如调用 std::sin)。
- 必须包含
<type_traits> - 使用
std::is_floating_point_v<T>(C++17 变量模板别名)比写std::is_floating_point<T>::value更简洁 - 分支内不能出现对非浮点类型非法的操作,否则即使不执行也会编译失败
template <typename T>
auto safe_sin(T x) {
if constexpr (std::is_floating_point_v<T>) {
return std::sin(x); // 仅当 T 是浮点时才参与编译
} else {
return x; // 其他类型直接返回原值
}
}怎么用在 SFINAE 或 requires 约束里
在需要显式约束模板参数的场景下(比如重载函数、概念约束),std::is_floating_point 可以作为 SFINAE 条件或 requires 子句的一部分。
立即学习“C++免费学习笔记(深入)”;
- SFINAE 写法:用
std::enable_if_t<std::is_floating_point_v<T>>* = nullptr作默认参数 - Concepts 写法(C++20):直接写
requires std::is_floating_point_v<T>或更自然地用std::floating_point概念(它是基于std::is_floating_point实现的) - 注意:
std::floating_point是 C++20 标准概念,语义等价但更推荐用于 requires,而std::is_floating_point是底层元函数,适合通用元编程组合
template <typename T>
auto legacy_overload(T x) -> std::enable_if_t<std::is_floating_point_v<T>, T> {
return x * 2;
}常见误判和边界情况
std::is_floating_point 的判定非常严格,只认标准浮点类型及其 cv 限定版本(如 const float、volatile double),其他一概返回 false。
-
std::is_floating_point_v<float&>→false(引用不是浮点类型) -
std::is_floating_point_v<std::complex<float>>→false(复数模板不是浮点类型) -
std::is_floating_point_v<int>→false(整型当然不行) -
std::is_floating_point_v<const double>→true(cv 限定不影响判定) - 自定义浮点类(如
half)默认不被识别,除非你特化std::is_floating_point(不推荐,破坏标准行为)
如果要支持用户自定义浮点语义,应另建概念(例如检查是否存在 operator+、std::numeric_limits 特化等),而不是依赖 std::is_floating_point。


















