I have a data structure like this: map<string, map<string, map<string, MyObj>>>
Now, I have multiple functions all of which use the same for loop method:
for (auto p1 : myMap)
for (auto p2 : p1.second)
for (auto p3 : p2.second)
doThingsWith(p1, p2, 3);
Where the doThingsWith(p1, p2, p3)
varies between functions, as well as the code before and after the for loops. Also, some functions only need to access MyObj
objects for example, while others need access to all the string keys as well as the MyObj
objects.
So, the question is, is there any method to generalise this without losing performance? I came up with a function that returns a vector of tuples:
vector<tuple<string, string, string, MyObj>> getData(... &myMap)
{
vector<tuple<string, string, string, MyObj>> data;
for (auto p1 : myMap)
for (auto p2 : p1.second)
for (auto p3 : p2.second)
data.push_back(tuple<string, string, string, MyObj>(
p1.first, p2.first, p3.first, p3.second
));
return data;
}
And now my functions can use this:
for (auto t : getData(myMap))
doThingsWith(get<0>(t), get<1>(t), get<2>(t), get<3>(t));
But this is unnecessarily constructs a lot of tuples and vectors, since myMap
is huge.
Is there any better way? In Python I can use generators, but I don't know the C++ equilevant:
def iterTuples(myMap):
for k1, v1 in myMap.items():
for k2, v2 in v1.items():
for k3, v3 in v2.items():
yield k1, k2, k3, v3
for k1, k2, k3, val in iterTuples(myMap):
doThingsWith(k1, k2, k3, val)