C++映射插入问题,对象包含另一个映射



我有包含其他映射的无序映射容器。

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*>>>;

tripo只是int和trip_departureo的一对。然后我使用容器:

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个标记。然后我将最后一个令牌(时间(转换为小时和分钟,并将其打包为一个int。现在问题来了。我成功地创建了trip_departure td,通过测试输出,我知道里面有所有的变量。然后我初始化了trip_o tr。第一个变量在那里,但当我想获得第二个变量时,我得到了一个错误:

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

在以下行引发异常:

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

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

问题出现在第二个atv[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 ...                 ^

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

最新更新