You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用std::variant作为unordered_map值类型插入时运行挂起问题

问题成因
  • 核心问题是nlohmann::json的泛型隐式转换逻辑与std::variant构造逻辑冲突:代码中直接将json对象传入vector初始化列表构造variant时,编译器无法匹配到最优的类型转换路径,会触发无限递归的类型转换尝试,最终栈溢出导致程序被系统杀死。
  • 本次崩溃刚好出现在key为t的场景,是因为该key对应的值为大整数1608008400000,刚好处于long、double两种类型的可表示范围重叠区间,进一步加剧了类型匹配的歧义性。
解决方法

完全规避隐式转换,先判断json值的实际类型,显式转换为variant对应的备选类型后再存入容器即可,修改后的代码如下:

#include <nlohmann/json.hpp>
#include <unordered_map>
#include <variant>
#include <iostream>
#include <string> 
#include <cstdint>

using json = nlohmann::json;

int main() {
    // 可选优化:将long替换为int64_t,适配所有平台的大整数场景,避免溢出
    using ValueVariant = std::variant<double, long, std::string>;
    std::unordered_map<std::string, std::vector<ValueVariant>> mp;

    json input = "{ \"happy\": \"yes\", \"pi\": 3.141, \"t\": 1608008400000 }"_json;

    for(auto& el : input.items()) { 
        if (mp.find(el.key()) != mp.end()) {
            continue;
        }
        std::cout << "trying insertion for key " << el.key() << std::endl;
        ValueVariant val;
        if (el.value().is_string()) {
            val = el.value().get<std::string>();
        } else if (el.value().is_integer()) {
            val = static_cast<long>(el.value().get<int64_t>());
        } else if (el.value().is_number_float()) {
            val = el.value().get<double>();
        }
        mp.insert({ el.key(), std::vector<ValueVariant>{val} });
        std::cout << "inserted " << el.key() << " successfully!" << std::endl;
    }
    return 0;
}
额外优化建议

如果你的业务场景需要处理跨平台的大整数值,可直接将variant中的long替换为std::int64_t,完全避免整数溢出风险。

内容的提问来源于stack exchange,提问作者idm2114

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 07:27:03