Search code examples
c++for-loopc++11stdmapstd

C++ value as map: Value is not updating in second map


I have a std::map with value as another map. I want to update the value of inner map.

When inner map values is update and print immediately, it shows the updated value. But after that when a display function is called, it doesn't show the updated value. Not sure what I'm missing.

#include <iostream>
#include <map>

typedef  std::map <std::string, std::string> poolNameApnNameT;

struct A
{
    struct S
    {
        std::map <std::string, poolNameApnNameT>apnPoolValidationDb;
    }s;
    void PrintfMe();
};

void A::PrintfMe()
{
    for(auto x: s.apnPoolValidationDb) {
        std::cout << "main: " << x.first << std::endl;
        for (auto y: x.second)
            std::cout << "Inner: " << y.first << " " << y.second << std::endl;
    }
}

int main()
{
    A a;

    a.s.apnPoolValidationDb.emplace(
        std::make_pair((char*)"pool1",
        poolNameApnNameT({ std::make_pair((char*)"pool2","xx")})
    ));

    a.s.apnPoolValidationDb.emplace(
        std::make_pair((char*)"pool2",
        poolNameApnNameT({ std::make_pair((char*)"pool1","zz")})
    ));


    a.PrintfMe();


    /* search key and updated value's value(inner map).*/
    for (auto search: a.s.apnPoolValidationDb) {
        auto search2 = search.second.find("pool2");
        if(search2 != search.second.end()) {
            std::cout << "found: " << search2->first << std::endl;
            std::cout << "Updating: " << search2->second << std::endl;
            search2->second.assign((char*)"yy"); // Update using assign()
            std::cout << "After Update " << search2->second << std::endl;

            search.second[search2->first] = "OO"; // Update using []
            std::cout << "After Update " << search2->second << std::endl;
        }
    }

    std::cout << std::endl;

    a.PrintfMe();
}

Output:

main: pool1
Inner: pool2 xx
main: pool2
Inner: pool1 zz

found: pool2
Updating: xx
After Update yy
After Update OO

main: pool1
Inner: pool2 xx  <<< should be OO instead of xx
main: pool2
Inner: pool1 zz

Solution

  • The problem is on this line:

    for(auto search: a.s.apnPoolValidationDb)
    

    this is a ranged-for loop over the key-value pairs in the outer map. But note the variable declaration! Your search variable is declared as an auto, not an auto&. So, you're actually making a copy of the inner maps in each iteration of this loop. You're updating the copy, not the original; and the copy is discarded when you continue to the next iteration. The original outer map remains unchanged.