std::is_integral只能检查类型而非变量,正确用法是std::is_integral_v;它在编译期判定标准整数类型(如int、bool、char等),不适用于运行时数值判断。

std::is_integral 不能检查变量,只能检查类型
这是最常被误解的一点:std::is_integral 是一个类型特征(type trait),它接受的是**类型名**,不是变量名。写成 std::is_integral<decltype>::value</decltype> 才合法;直接传变量(如 std::is_integral<x></x>)会编译失败。
它在编译期求值,返回一个 std::integral_constant<bool true></bool>,所以通常用 ::value 或 C++17 的 v 后缀(如 std::is_integral_v<t></t>)取布尔值。
- ✅ 正确:
std::is_integral_v<decltype></decltype>→true - ✅ 正确:
std::is_integral_v<long long></long>→true - ❌ 错误:
std::is_integral(5 不是类型) - ❌ 错误:
std::is_integral<x></x>(x 是变量,不是类型)
在模板约束中用 requires + std::is_integral_v 限制参数类型
C++20 概念(concepts)让约束更直观。直接用 requires std::is_integral_v<t></t> 可以让编译器在模板实例化时拒绝非整型实参,报错信息比 SFINAE 清晰得多。
注意:必须用 std::is_integral_v<t></t>(类型参数 T),不能写 std::is_integral_v<decltype></decltype>——因为此时 x 还未声明,且约束发生在形参类型推导阶段。
立即学习“C++免费学习笔记(深入)”;
template <typename T>
requires std::is_integral_v<T>
T square(T x) {
return x * x;
}- ✅
square(7)→ OK(int满足) - ✅
square(3LL)→ OK(long long满足) - ❌
square(3.14)→ 编译错误,提示 “constraint not satisfied”
std::is_integral 对 char、bool、enum 等类型的判定结果
它判断的是“是否为标准整数类型”,不看值,只看类型定义。C++ 标准明确列出哪些是 integral type:bool、char、signed/unsigned char、short、int、long、long long 及其带符号/无符号变体,还有 char8_t / char16_t / char32_t / wchar_t。
-
std::is_integral_v<char></char>→true(尽管常用于字符) -
std::is_integral_v<bool></bool>→true(标准规定 bool 是整型) -
std::is_integral_v<enum e></enum>→false(枚举类型默认不是 integral type,除非显式用enum class E : int并配合std::underlying_type_t检查底层类型) -
std::is_integral_v<:size_t></:size_t>→true(它是unsigned类型的别名)
容易忽略的是:cv 限定符(const int、volatile short)不影响结果,std::is_integral_v<const int></const> 仍为 true;但引用类型(int&)、指针(int*)、数组(int[3])全都不满足。
替代方案:运行时判断值是否为整数?那得另想办法
如果真想检查一个 double 变量的值是否“数学上等于某个整数”(比如 3.0 或 -5.0),std::is_integral 完全无用——它连运行时值都碰不到。
这种需求属于数值计算范畴,得用浮点比较:
bool is_whole(double x) {
return std::abs(x - std::round(x)) < 1e-9;
}或者对 std::string 输入做解析验证,而不是依赖类型特征。混淆编译期类型属性和运行时数值性质,是元编程初学者最容易卡住的地方。









