std::is_integral_v用于编译期判断类型是否为整数类型(含bool、枚举),返回true仅当t是c++内置整数类型;它不适用于运行时值的整数性校验,后者需用std::from_chars或std::modf等结合范围检查实现。

用 std::is_integral_v 判断类型是否为整数类型
编译期判断一个类型是不是 C++ 内置整数类型(比如 int、short、unsigned long long 等),最直接的方式是用标准库的类型特征:std::is_integral_v<t></t>。它返回 true 当且仅当 T 是整数类型(含 bool 和枚举,不含浮点、指针、类等)。
注意:这是对「类型」的判断,不是对「变量值」的判断。比如 double x = 5.0;,std::is_integral_v<decltype></decltype> 仍是 false,哪怕它的值看起来像整数。
-
std::is_integral_v<int></int>→true -
std::is_integral_v<const int></const>→true(引用和 cv 限定不影响) -
std::is_integral_v<double></double>→false -
std::is_integral_v<:string></:string>→false
运行时怎么知道一个 double 或 std::string 的值“算不算整数”
用户真正想问的,常常不是类型,而是“这个值能不能无损转成 int”。比如从 JSON 解析出一个 double,或从命令行读入一个 std::string,需要确认它是否表示一个合法整数。
关键点在于:不能只看有没有小数点,还要处理科学计数法、前导空格、符号、溢出、非数字字符等。
立即学习“C++免费学习笔记(深入)”;
- 对
std::string:推荐用std::from_chars(C++17 起),它不抛异常、不依赖 locale、能精确报告解析位置和错误类型 - 对
double:先用std::modf拆出小数部分,再检查是否为 0;但必须额外判断是否在int表示范围内(比如1e18是整数,但远超int最大值) - 避免用
std::stoi直接转换再捕获异常——它对超出范围的输入行为未定义(可能截断或抛std::out_of_range),且无法区分 "123abc" 和 "123"
std::from_chars 解析字符串到整数的正确姿势
std::from_chars 是目前最可靠、最轻量的字符串转整数方案,尤其适合高频或嵌入式场景。它不分配内存、不抛异常、返回详细结果。
典型用法:
int value;
auto res = std::from_chars(str.data(), str.data() + str.size(), value);
if (res.ec == std::errc{}) {
// 成功,且 res.ptr 指向第一个未消费的字符
if (res.ptr == str.data() + str.size()) {
// 全部字符都被消费 → 纯整数字符串,如 "123"
} else {
// 后面还有内容,如 "123abc" → 通常视为非法
}
} else if (res.ec == std::errc::invalid_argument) {
// 格式错误,如 "abc" 或 ""
} else if (res.ec == std::errc::result_out_of_range) {
// 数值超出 int 范围,如 "2147483648"(对 32 位 int)
}
- 必须检查
res.ptr是否走到末尾,否则 "123x" 会被当成成功解析出 123 - 不同整数类型要传对应变量(
long long就用long long value;),模板参数不可省略 - 不支持带空格或制表符的字符串,需提前 trim;也不支持十六进制前缀(
"0x"),除非显式指定std::chars_format::hex
为什么不用 dynamic_cast 或 typeid 判断 int
有人会想到运行时类型识别(RTTI),比如对某个基类指针做 dynamic_cast,或者比对 typeid。这完全走错方向:
-
dynamic_cast只适用于多态类体系,int是内置类型,不支持 -
typeid对内置类型有效,但只能用于类型名比较(如typeid(x) == typeid(int)),仍属于编译期可推导的类型判断,不是值语义 - 更重要的是:RTTI 开销大、可被编译器关闭(
-fno-rtti),而类型判断本该是零成本抽象
类型是否为整数,是编译期问题;值是否能表达为整数,是运行时输入校验问题——混用两者,八成会掉坑里。
最常被忽略的一点:整数性判断永远要绑定具体上下文。是想转成 int?还是 long?还是只是验证 JSON 字段?没有统一答案,得看目标类型和容错要求。










