std::is_integral 是编译期类型特征,仅接受类型而非变量,正确用法为 std::is_integral_v 或 std::is_integral::value;它对 bool、char 等内置整数类型返回 true,但不识别 enum 和自定义整数类。

std::is_integral 是编译期判断,不是运行时函数
它不接受变量,只接受类型——传 int 可以,传 x(变量名)直接编译失败。常见错误是写成 std::is_integral(x) 或 std::is_integral<decltype>()</decltype>(少了个 ::value 或用错了模板语法)。
正确姿势是作为类型特征(type trait)使用,靠 ::value 或 C++17 的 ::value_v 拿到布尔结果:
static_assert(std::is_integral_v<int>); // ✅ static_assert(std::is_integral<char>::value); // ✅ static_assert(std::is_integral_v<double>); // ❌ 编译失败
- 必须用
typename修饰依赖类型(比如模板参数中),否则某些编译器报错 -
std::is_integral对bool、char、short、int、long、long long及其带signed/unsigned修饰的版本都返回true - 它不识别自定义整数类(哪怕重载了所有算术运算符),也不把
enum当整数——除非显式继承自std::integral_constant或用std::is_enum单独判断
和 std::is_arithmetic、std::is_fundamental 的区别在哪
容易混淆三者覆盖范围:std::is_integral 是 std::is_arithmetic 的子集,而 std::is_arithmetic 又是 std::is_fundamental 的子集。
-
std::is_integral_v<t></t>:仅限整数类型(含bool),排除float、double -
std::is_arithmetic_v<t></t>:包含整数 + 浮点(float、double、long double) -
std::is_fundamental_v<t></t>:再加void、nullptr_t、各类指针类型(但不含引用、数组、函数类型)
举个实际场景:写一个只接受整数的模板函数,用 std::is_integral 最精准;若想同时支持浮点做数值计算,就该升一级用 std::is_arithmetic。
立即学习“C++免费学习笔记(深入)”;
在 SFINAE 和 concepts 中怎么安全使用
直接写 std::is_integral<t>::value</t> 在模板约束里可能触发硬错误(hard error),尤其当 T 是无效类型时。要避免,就得用 SFINAE 友好写法或 C++20 concepts。
- C++11/14 推荐用
std::enable_if_t<:is_integral_v>></:is_integral_v>做返回类型或默认模板参数 - C++20 能直接写
template<:integral t></:integral>(注意:这是 concept,不是 trait,且std::integral概念等价于std::is_integral_v<t></t>) - 别混用:比如
template<typename t> void f(T) requires std::is_integral_v<t></t></typename>是合法的,但requires std::is_integral<t></t>(漏掉::value_v)会编译失败
性能上没 runtime 开销——全是编译期计算;但过度嵌套(比如多层 enable_if 套娃)会让错误信息变得极难读。
为什么 char 和 bool 算整数,但 enum 不算
这是标准明确规定的:C++ 标准将 bool 和所有字符类型(char、signed char、unsigned char、char8_t 等)归为“整数类型”,所以 std::is_integral 返回 true。
而枚举类型(enum、enum class)虽底层用整数存储,但语义上是独立类型,标准要求 std::is_integral 对它们返回 false。
- 如果真需要“能无损转成整数的类型”,得组合判断:
std::is_integral_v<t> || std::is_enum_v<t></t></t> -
std::underlying_type_t<someenum></someenum>才是那个整数类型,可用std::is_integral_v<:underlying_type_t>></:underlying_type_t>验证 - 别依赖
sizeof(enum)判断——它只反映存储大小,不等于类型分类
最常被忽略的是:char16_t、char32_t 属于整数类型(std::is_integral_v 为 true),但 wchar_t 是否算整数取决于平台——MSVC 认它是,GCC/Clang 在某些配置下可能不认,得实测 std::is_integral_v<wchar_t></wchar_t>。










