讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何读取YAML中的长整型int64_t_as模板特化用法【实战】

夏强同学_1527

夏强同学_1527

发布时间:2026-04-06 18:38:34

|

649人浏览过

|

来源于php中文网

原创

yaml-cpp 0.8.0+ 默认将整数解析为 double,导致 int64_t 精度丢失;需手动特化 YAML::convert<int64_t> 并确保其定义在首次 as<int64_t>() 调用前生效,否则仍走 double 中转。

c++如何读取yaml中的长整型int64_t_as模板特化用法【实战】

yaml-cpp 读取 int64_t 时默认转成 double 的坑

yaml-cpp(0.8.0+)默认把长整型数字(如 9223372036854775807)解析为 double,哪怕 YAML 文件里写的是整数形式。这不是 bug,是设计:它优先用浮点表示所有数字以兼容科学计数法,但代价是丢失 int64_t 精度(double 在 2⁵³ 以上无法精确表示整数)。你调用 as<int64_t>()</int64_t> 会触发隐式转换,可能溢出或截断。

正确启用 int64_t 支持需手动注册模板特化

yaml-cpp 不内置 int64_t 的序列化/反序列化逻辑,必须显式特化 YAML::convert<T>。否则 node.as<int64_t>()</int64_t> 会 fallback 到通用数字转换路径,走 double 中转。

  • 在你的代码中(通常放在 .cpp 文件顶部或单独头文件),添加如下特化:
namespace YAML {
template <>
struct convert<int64_t> {
    static Node encode(const int64_t& rhs) {
        Node node;
        node = static_cast<long long>(rhs); // 避免平台 long 大小歧义
        return node;
    }
    static bool decode(const Node& node, int64_t& rhs) {
        if (!node.IsScalar()) return false;
        try {
            // 先尝试整数解析(支持十进制、十六进制如 0xFF)
            rhs = std::stoll(node.Scalar(), nullptr, 0);
            return true;
        } catch (const std::out_of_range&) {
            return false;
        } catch (const std::invalid_argument&) {
            // fallback:尝试作为 double 解析再转(仅当确定不会精度丢失时)
            if (node.IsScalar() && node.Scalar().find('.') == std::string::npos) {
                try {
                    rhs = static_cast<int64_t>(std::stod(node.Scalar()));
                    return true;
                } catch (...) {}
            }
            return false;
        }
    }
};
}
  • 必须确保该特化在任何调用 as<int64_t>()</int64_t> 之前完成编译(不能只在头文件声明,要定义)
  • 不要在头文件里重复定义,否则链接时报 multiple definition
  • std::stoll(..., 0) 自动识别 0x、0 前缀,比硬写 base=10 更健壮

读取时直接用 as<int64_t>(),别依赖 operator>>

operator>>(即 node >> value)底层仍走 decode,但容易被误认为“更底层”,其实和 as<>() 等价;而 as<>() 语义更明确、调试时更容易定位问题。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 安全读取示例:
YAML::Node config = YAML::LoadFile("config.yaml");
int64_t timeout_ms = config["timeout_ms"].as<int64_t>(); // ✅ 触发你注册的 decode
  • 如果字段可能缺失或类型错误,加判断:
if (config["timeout_ms"] && config["timeout_ms"].IsScalar()) {
    try {
        int64_t val = config["timeout_ms"].as<int64_t>();
        // use val
    } catch (const YAML::BadConversion& e) {
        // 处理解析失败,比如日志 + 默认值
    }
}

注意 YAML 文件本身的数字书写格式

即使你注册了特化,YAML 解析器在词法分析阶段就决定了 token 类型。如果数字带小数点(如 1000.0)或指数(如 1e6),yaml-cpp 会直接标记为 float token,你的 decode 函数根本不会被调用——因为 node.IsScalar() 成立,但 node.Type() 是 YAML::NodeType::Scalar,内容却是浮点字面量。

立即学习“C++免费学习笔记(深入)”;

  • 确保 YAML 中长整型写成纯整数形式:9223372036854775807,而非 9223372036854775807.0 或 0x7FFFFFFFFFFFFFFF(后者虽能被 stoll 解析,但不是标准 YAML 整数格式,部分编辑器/校验工具会报错)
  • 十六进制支持靠 stoll 实现,不是 yaml-cpp 原生能力,所以 0xFF 可行,但 0b1010 不行(stoll 不支持二进制)
  • 超大整数字符串(如超过 20 位)建议用引号包裹成字符串再手动解析,避免 yaml-cpp 早期版本误判为 float
特化 YAML::convert<int64_t> 是必要步骤,漏掉它,所有“读取 int64_t”都是假象——背后全是 double 中转和潜在精度腐蚀。真正麻烦的不是写特化,而是忘记它只在定义它的编译单元生效,跨文件调用时静默失效。

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

6287

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

724

2025.10.23

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

13366

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1605

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3637

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

5801

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1698

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2584

2023.09.04

VibeKnow知识视频制作与导出详解
VibeKnow知识视频制作与导出详解

本专题整理VibeKnow从注册、素材上传、AI生成到预览导出的完整操作,帮助新手快速制作第一条知识讲解视频。

0

2026.10.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn