C++ 怎么判断是不是int C++ 检查变量是否为整数【技巧】

3次阅读

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

C++ 怎么判断是不是int C++ 检查变量是否为整数【技巧】

std::is_integral_v 判断类型是否为整数类型

编译期判断一个类型是不是 C++ 内置整数类型(比如 intshortunsigned 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

运行时怎么知道一个 doublestd::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_casttypeid 判断 int

有人会想到运行时类型识别(RTTI),比如对某个基类指针做 dynamic_cast,或者比对 typeid。这完全走错方向:

  • dynamic_cast 只适用于多态类体系,int 是内置类型,不支持
  • typeid 对内置类型有效,但只能用于类型名比较(如 typeid(x) == typeid(int)),仍属于编译期可推导的类型判断,不是值语义
  • 更重要的是:RTTI 开销大、可被编译器关闭(-fno-rtti),而类型判断本该是零成本抽象

类型是否为整数,是编译期问题;值是否能表达为整数,是运行时输入校验问题——混用两者,八成会掉坑里。

最常被忽略的一点:整数性判断永远要绑定具体上下文。是想转成 int?还是 long?还是只是验证 JSON 字段?没有统一答案,得看目标类型和容错要求。

text=ZqhQzanResources