Oliver
Oliver

Reputation: 3682

Map of Map data struct confusion

I am trying to setup a map of map structure in C++ but can't make it work as expected. I put together this sample program to illustrate the issue. Please excuse the mess if it seems convoluted but I want to preserve the case as much as I can.

So the current print out is: L1, size = 0 and what I was expecting is something like:

L1, size 1
   L2, 4

It seems like the second level map is not established properly, maybe a scoping issue, but I can't quite figure it out. The program is as the following:

// So the map is
// AKEY -> { BKEY -> [ SegPair, SegPair  .... ] }

#include <map>
#include <utility>
#include <iostream>
#include <vector>

typedef std::string AKEY;
typedef std::string BKEY;

typedef std::pair<int,int> SegPair;
typedef std::vector<SegPair> SegVec;
typedef std::map<BKEY, SegVec> Ensemble;
typedef std::map<AKEY, Ensemble> Oracle;

using std::string;

Oracle o = Oracle();

void setup(string akey, string bkey, int x, int y) {
    auto pos = o.find(akey);
    if (pos == o.end()) {
        o[akey] = Ensemble();
    }

    Ensemble e = o[akey];

    auto pos2 = e.find(bkey);
    if (pos2 == e.end()) {
        e[bkey] = SegVec();
    }

    SegPair p(x, y);
    e[bkey].push_back(p);
}

int main(void) {

    setup("L1", "L2", 3, 4);

    for (auto it = o.begin(); it != o.end(); it++) {
        std::cout << it->first;
        Ensemble e = it->second;
        std::cout << ", size = " << e.size() << "\n";
        for (auto it2 = e.begin(); it2 != e.end(); it2++) {
            std::cout << "\t" << it2-> first << "\n";
            SegVec v = it2->second;
            for (int i = 0; i < v.size(); i++)
                std::cout<< v[i].second << " ";
        }
    }
}

Upvotes: 1

Views: 85

Answers (2)

molbdnilo
molbdnilo

Reputation: 66371

In setup, e is a copy of the object in o.
When you modify it, you're not modifying anything in o.

To fix, use a reference:

Ensemble& e = o[akey];

That will make e refer to the same thing as o[akey] instead of a copy.

Upvotes: 1

Scott Jones
Scott Jones

Reputation: 2908

I think your problem is with this line:

Ensemble e = o[akey];

You're creating a local, rather than capturing the lvalue in the map by reference, for mutation. Thus, any changes you make to e after that point will simply be discarded when e goes out of scope.

Upvotes: 2

Related Questions