0

Hey guys!

I'm just getting into c++ and after learning stuff about reference and value pass I've come across a problem.

So basically I'm trying to copy a map and I do so in my method. So far the size of the 2 maps are the same.

The problem comes when I insert some new values into the original map because it doesn't change the copied map.

So my question is how do I copy/pass a map, with the new map being a real copy and when the original changes, the copied version does so.

I'll attach the code that I was working on.

The code:

#include <iostream>
#include <map>

using namespace std;

map<string, int> passMapByReference(map<string, int>& temp_map){
 return temp_map;   
}

void printMap(map<string, int>& temp_map ){
    cout << temp_map.size() << endl;
}

int main()
{
    map<string, int> copyMap;
    
    map<string, int> map;
    map["asd"] = 1;
    map["dsa"] = 2;
    
    printMap(map);

    copyMap = passMapByReference(map);
    
    printMap(copyMap);
    
    map["ksdbj"] = 3;
    map["askdnijabsd"] = 4;
    
    printMap(map);
    
    //this should print 4
    printMap(copyMap);
    

    return 0;
}

The output:

2
2
4
2
SuperBlaze
  • 37
  • 5

1 Answers1

1

map and copyMap are separate objects and so changing one won't affect other. Moreover, you're returning the map by value from the function passMapByReference. Instead you could return the map by reference from passMapByReference as shown below:

#include <iostream>
#include <map>
#include <string>

//------------------------v------->return by reference
std::map<std::string, int>& passMapByReference(std::map<std::string, int>& temp_map){
 return temp_map;   
}

void printMap(std::map<std::string, int>& temp_map ){
    std::cout << temp_map.size() << std::endl;
}

int main()
{  
    std::map<std::string, int> map;
    map["asd"] = 1;
    map["dsa"] = 2;
    
    printMap(map);

    //copyMap is an lvalue reference to passMapByReference
    std::map<std::string, int>& copyMap = passMapByReference(map);
    
    printMap(copyMap);
    
    map["ksdbj"] = 3;
    map["askdnijabsd"] = 4;
    
    printMap(map);
    
    printMap(copyMap);//prints 4
    

}

Working demo

The output of the above program is:

2
2
4
4

Note

I noticed that you have used using namespace std; and then created a map with the name map. This should be avoided as it creates confusion. For example, it becomes hard to see whether the map you're referring to is a std::map or the variable named map. I would recommend using std:: to qualify the standard contianers instead of using using namespace std;.

Refer to Why is "using namespace std;" considered bad practice?

Jason
  • 36,170
  • 5
  • 26
  • 60
  • Thank you very much!! Yes I forgot to remove using namespace. Basically I get the same result in my code if I write std::map& copyMap = map; So the function is basically useless.. – SuperBlaze May 21 '22 at 18:45
  • One last question. The whole reason I wanted to create the copy array is because I want to create an array of maps in the same way. How do I do that? So far I had std::map* data_ = new ...; So in this case if I want to store references how should I declare it? – SuperBlaze May 21 '22 at 18:50
  • @SuperBlaze We cannot store references in an array(or a vector etc). You can store pointers in an array(or a vector etc) though. If you do decide to store pointers that point to dynamically allocated memory then consider using smart pointers so that you won't have to use `new` and `delete` manually. You can also refer to [Why can't I make a vector of references?](https://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references). Feel free to ask a separate follow up question so that you can describe your case there in more detail than here in comments. – Jason May 21 '22 at 18:55
  • Thank you again! I'll ask a separate question then! – SuperBlaze May 21 '22 at 18:57