Home > Software design >  Modify maps by reference in template class
Modify maps by reference in template class

Time:05-23

Hey guys!

I have school project to make. In the project I have to create a map_storage template class that's able to store/ know what maps it's going to modify and do different operations on them.

The main.cpp file was already created for me, so that I can check if my code was correct.

Template class:

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

#ifndef MAPALIGN_H
#define MAPALIGN_H

template<class Key, class T, class Compare = std::less<Key> >
class map_storage{
public:

    void add(std::map<Key, T, Compare> &temp_map){
        data_.push_back(temp_map);
    }

    void doSomething(){
        std::cout << data_.size() << std::endl;
        //This does something to all maps in the vector.
    }

private:
    std::vector<std::map<Key, T, Compare> > data_;

};

#endif

When I modify the maps in data_ (add new key,values etc.) I want to see the changes in main too and the same thing for the other way around.

My question is that How can I store the references of the maps in a template class?

Example of the main method:

#include <iostream>
#include "mapalign.h"
#include <string>
#include <map>

int main()
{
  std::map<std::string, int> map1;
  
  map_storage<std::string int> ms;
  
  ms.add(map1);
  
  map1["asd"] = 1;
  map1["dsa"] = 2;
  

  ms.doSomething();
  //Tests that are checking that operations on map1 were finished on the map with size of 2 and not the empty one.

  .....

  return 0;
}

So in the main.cpp file its mandatory that all modifications are shown on the maps reference that was added to the template class.

In this case the doSomething() function does something with the map that has "asd" 1, "dsa" 2 key-value pairs, and not just the empty copy of the map that was added earlier to the vector.

During the doSomething() operation we have to know all map data to accordingly modify data in the other maps.

If anyone has any idea to this problem I would really appreciate it.

(I know that c does not support storing references in an array nor vector, so there must be another way that I can't figure out)

Thank you again.

CodePudding user response:

We cannot have vector of lvalue references. You could instead store pointers inside the vector as shown below:

template<class Key, class T, class Compare = std::less<Key> >
class map_storage{
public:
//------------------------------------v--------------->pointer
    void add(std::map<Key, T, Compare>* temp_map){
        data_.push_back(temp_map);
    }

    void doSomething(){

        std::cout << data_.size() << std::endl;
        std::cout<< data_.at(0)->size(); //prints 2
        
    }

private:
//---------------------------------------v------------->pointer
    std::vector<std::map<Key, T, Compare>* > data_;

};

int main()
{
  std::map<std::string, int> map1;

  map_storage<std::string, int> ms;
//-----------------------^----------->added comma here which was missing in the original code
  
  ms.add(&map1);
  
  map1["asd"] = 1;
  map1["dsa"] = 2;
  
  
  ms.doSomething();
  
}

Working demo

Also, make sure that the you don't dereference pointers that are pointing to objects that no longer exist.

Method 2

template<class Key, class T, class Compare = std::less<Key> >
class map_storage{
public:
//------------------------------------v--------------->reference
    void add(std::map<Key, T, Compare>& temp_map){
        data_.push_back(&temp_map);
    }

    void doSomething(){

        std::cout << data_.size() << std::endl;
        std::cout<< data_.at(0)->size(); //prints 2
        
    }

private:
//---------------------------------------v------------->pointer
    std::vector<std::map<Key, T, Compare>* > data_;

};

int main()
{
  std::map<std::string, int> map1;

  map_storage<std::string, int> ms;
//-----------------------^----------->added comma here which was missing in the original code
  
  ms.add(map1);
  
  map1["asd"] = 1;
  map1["dsa"] = 2;
  
  
  ms.doSomething();
  
}

Working demo

  • Related