Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I serialize map of STL in MFC using CArchive?

I need to write the content of a map (key is ID of int, value is of self-defined struct) into a file, and load it from the file later on. Can I do it in MFC with CArchive?

Thank you!

like image 677
user26404 Avatar asked Nov 04 '08 08:11

user26404


2 Answers

In MFC, I believe it's easiest to first serialize the size of the map, and then simply iterate through all the elements.

You didn't specify if you use std::map or MFC's CMap, but a version based on std::map could look like this:

void MyClass::Serialize(CArchive& archive)
{
  CObject::Serialize(archive);
  if (archive.IsStoring()) {
    archive << m_map.size(); // save element count
    std::map<int, MapData>::const_iterator iter = m_map.begin(), 
                                           iterEnd = m_map.end();
    for (; iter != iterEnd; iter++) {
      archive << iter->first << iter->second;
    }
  }
  else {
    m_map.clear();
    size_t mapSize = 0;
    archive >> mapSize; // read element count
    for (size_t i = 0; i < mapSize; ++i) {
      int key;
      MapData value;
      archive >> key;
      archive >> value;
      m_map[key] = value;
    }
  }
}

If an error occurs when reading the archive, one of the streaming operations should throw an exception, which would then be caught by the framework on a higher level.

like image 185
Reunanen Avatar answered Oct 26 '22 07:10

Reunanen


I don't know much about MFC, but your problem is rather trivially solved using Boost.Serialization

struct MapData {
     int m_int;
     std::string m_str;

  private: 
    friend class boost::serialization::access; 

    template<class Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
        ar & m_int; 
        ar & m_str; 
    } 
};

std::map< int, MapData > theData;

template<class Archive>
void serialize(Archive & ar, std::map< int, MapData > & data, const unsigned int version)
{
    ar & data;
}

And then later were you want to do the real archiving:

std::ofstream ofs("filename"); 
boost::archive::binary_oarchive oa(ofs); 
oa << theData; 

That's it.

(disclaimer: code simply typed in this box, not tested at all, typo's were intended ;)

like image 28
Pieter Avatar answered Oct 26 '22 06:10

Pieter