首页 > 解决方案 > 插入挂在运行时的 unordered_map

问题描述

我遇到了一个我只能描述为完全不熟悉的问题,我可以使用一些帮助。就上下文而言,我对 c++ 编程知之甚少,并且正在努力学习更多,所以我目前正在编写的代码比其他任何东西都更具教育意义。我想创建一个unordered_map包含作为键的字符串和作为键的关联值的向量。传统上,这将是微不足道的。但是,我的程序正在尝试将 json 数据解析为这种unordered_map数据结构,并且无法保证预先知道每个向量的类型。我唯一可以保证的是,每个向量的类型将是以下类型集中的类型之一:string, int, double. 为了尝试实现以这种方式运行的 unordered_map,我尝试使用variant,但目前变体实现导致超时错误。我希望就超时的原因得到一些建议,理想情况下,如何解决它。

代码如下(复制此问题的最小示例):


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

using json = nlohmann::json;

int main() {
// map stores col name as string and vector with col type
    std::unordered_map<std::string, std::vector<std::variant<double, long, std::string>>> mp;

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

   for(auto& el : input.items()) { 
       if (mp.find(el.key()) == mp.end()) {
           std::cout << "trying insertion for key " << el.key() << std::endl;
           mp.insert({ el.key(), std::vector<std::variant<double, long, std::string>>{ el.value() } });
           std::cout << "inserted " << el.key() << " successfully!" << std::endl;
       }
    }
    return 0;
}

这是我的输入(请注意,我的输入以 nlohmann::json 类型传递给该程序): {"c":127.88,"h":127.9,"l":124.13,"n":867462,"o":124.34,"t":1608008400000,"v":157572262.0,"vw":126.5535},{"c":127.81,"h":128.37,"l":126.56,"n":550012,"o":127.41,"t":1608094800000,"v":95913591.0,"vw":127.5459}

这是当前的输出:

这是当前的输出

inserted c successfully!
trying insertion for key h
inserted h successfully!
trying insertion for key l
inserted l successfully!
trying insertion for key n
inserted n successfully!
trying insertion for key o
inserted o successfully!
trying insertion for key t
[1]    40305 killed     ./test

我试图解决关于为什么会发生这种情况的一系列潜在的不同问题,但我基本上通过反复试验确认,当我尝试将std::variant<std::string, long, double>用于我的向量类型时会出现问题。当我为所有向量分配一个统一类型(double例如)时,所有插入都可以正常工作。然而,问题是可扩展性之一。即使这个例子只包含双精度和长整数,在未来我希望能够解析一些看起来像这样 {"a": "test", "b": 1243.343, "c": 120910394023332} 的数据:没有错误并且返回值是(为了清楚起见显示类型):

a : vector<string>{"test"}, b : vector<double>{1243.343}, c : vector<long>{120910394023332}

如果有什么我可以澄清的有助于回答这个问题的,请告诉我,我会添加它。

标签: c++debugging

解决方案


以下向量声明:

std::vector<int> v{4};

这将创建一个具有 4 个值的向量默认初始化。这个重载std::vector的构造函数接受一个参数,它给出了向量的初始大小。

std::vector<std::variant<double, long, std::string>>{ el.value() } }

记住我的介绍,现在应该很明显这将调用相同的构造函数。

当我在调试器中单步执行上述代码时,我的调试器揭示了这样一个事实:当 1608008400000 被传递到构造函数中时,事情很快就变得松散了。我的计算机成功创建具有 1 万亿、6080 亿、800 万和 40 万值的向量的机会非常非常渺茫。

el.value()不返回变体。它返回一个 JSON 值,并且没有现成的机制将其转换为变体。您必须自己完成所有工作,例如:

   auto v=el.value();

   if (v.is_number())
   {
       if (v.is_number_float())
       {
           vv.emplace_back( (double)v);
       }
       else
       {
           vv.emplace_back( (long)v);
       }
   }
   else
   {
       vv.emplace_back( (std::string) v);
   }

   mp.insert({ el.key(), vv});

推荐阅读