包含另一个地图的对象的C ++地图插入问题

Posted

技术标签:

【中文标题】包含另一个地图的对象的C ++地图插入问题【英文标题】:C++ map insert problem with objects containing another map 【发布时间】:2021-01-07 12:51:34 【问题描述】:

我有包含其他地图的无序地图容器。

using name = std::string;
using stop_o = std::pair<name, std::unordered_map<key,/**/ std::pair<name, std::unordered_map<key, std::pair<name, std::map<packed_time, std::pair<packed_time, std::pair < int, std::map<int, std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>>>>>>>>>>;
using platform_o = std::pair<name, std::unordered_map<key,/**/ std::pair<name, std::map<packed_time, std::pair<packed_time, std::pair < int, std::map<int, std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>>>>>>>>;
using platform_route_o = std::pair<name, std::map<packed_time,/**/ std::pair<packed_time, std::pair < int, std::map<int, std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>>>>>>;
using route_departure_o = std::pair<packed_time,/**/ std::pair < int, std::map<int, std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>>>>;
using trip_o = std::pair < int, std::map<int,/**/ std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>>>;
using trip_departure_o = std::pair<int, std::pair<packed_time, std::pair<name, timetable*>>>;

trip_o 只是一对 int 和 trip_departure_o。 然后我使用容器:

using stop_container = std::unordered_map<key, stop_o>;
using platform_container = std::unordered_map<key, platform_o>;
using platform_route_container = std::unordered_map<key, platform_route_o>;
using route_departure_container = std::map<packed_time, route_departure_o>;
using trip_container = std::unordered_map < int, trip_o>;
using trip_departure_container = std::map<int, trip_departure_o>;

// main object - put something inside
class timetable 
    public:
    stop_container timetable_stops;
    trip_container timetable_trips;
;

我的代码是:

void read_timetable(timetable& tt, std::istream& ifs)

    std::string line, token;
    ifs.ignore(1000, '\n');
    while (std::getline(ifs, line, '\n'))
    
        std::vector<std::string> v;
        std::stringstream entry(line);
        while (std::getline(entry, token, '\t'))
        
            v.push_back(token);
        
        std::vector<int> time;
        std::stringstream t(v[5]);
        while (std::getline(t, token, ':'))
        
            time.push_back(stoi(token));
        
        packed_time pt = pack_time(time[0], time[1]);

        if (tt.timetable_stops.find(v[4]) == tt.timetable_stops.end())
        
            trip_departure_o td;
            td.first = stoi(v[2]);
            td.second.first = pt;
            td.second.second.first = v[4];
            td.second.second.second = &tt;

            trip_o tr;
            tr.first = stoi(v[1]);
            tr.second.insert( stoi(v[1]), td );
            std::cout << tr.second.at(stoi(v[1])).first << std::endl;

            route_departure_o rd;
            rd.first = pt;
            rd.second = tr;
            std::cout << rd.second.first << std::endl;

            platform_route_o pr;
            pr.first = v[0];
            pr.second.insert( pt, rd );
            std::cout << pr.second.at(pt).first << std::endl;

            platform_o p;
            p.first = v[3];
            p.second.insert( v[3], pr );

            stop_o s;
            s.first = v[4];
            s.second.insert( v[4], p );
            std::cout << s.second.at(v[4]).first << std::endl;

            tt.timetable_stops.insert( v[4], s );

            std::cout << tt.timetable_stops.at(v[4]).second.at(v[3]).first;
            
        
... .. .

我每次都将行从输入拆分为 6 个标记。然后我将最后一个令牌(时间)转换为小时和分钟并将其打包为一个整数。 现在问题来了。我成功地创建了trip_departure td,测试输出我知道其中有所有变量。然后我初始化trip_o tr。第一个变量在那里,但是当我想得到第二个实际上是前一个对象 td 时,我得到一个错误:

jr.exe 中 0x00007FFCBF09D759 处的未处理异常:Microsoft C++ 异常:内存位置 0x0000007FF891D410 处的 std::invalid_argument。

在这一行抛出异常:

std::cout << tt.timetable_stops.at(v[4]).second.at(v[3]).first;

看起来它没有插入到地图中。但为什么呢?

【问题讨论】:

你试过调试吗?请提供minimal reproducible example。猜测您的 stoi 调用之一由于非数字字符串而失败 是的,我试过了,为什么? 如果没有 minimal reproducible example 很难判断,您的调试器应该在未处理的异常上停止,检查调用堆栈以找出异常是从哪里引发的 是的,在这一行抛出异常:std::cout @Rikib161999 您不需要如此复杂的代码来演示“将映射映射插入方法参数”。 minimal reproducible example 将只关注您感兴趣的一件事,并添加足够的上下文(声明/定义)以使代码完整。我看不到 十三个 类型的别名是展示地图所必需的。 【参考方案1】:

问题出在第二个at,与v[3]

第一个 at 返回对添加到时间表停靠点的 s 副本的引用。该副本的元素位于v[4],而不是v[3]。所以你要么想要

tt.timetable_stops.at(v[4]).second.at(v[4])

tt.timetable_stops.at(v[4]).second.at(v[4]).second.at(v[3])
//                 ^ returns copy of s
//                                  ^ returns copy of  v[4], p  originally stored in s
// returns copy of p stored in ...                 ^

如果您使用具有适当命名成员的适当结构而不是复杂的大量类型别名,这将更容易查看和诊断。

【讨论】:

以上是关于包含另一个地图的对象的C ++地图插入问题的主要内容,如果未能解决你的问题,请参考以下文章

检查一个地图是不是包含另一个地图的所有内容

Google Maps API JS - 从另一个JS文件访问标记位置

包含地图的对象?

引入百度地图js时产生的问题

将项目从一个向量复制到另一个向量

如何使用 JSTL 打印嵌套对象?