1
votes

I'm trying to serialize an InvertedIndex class I've made which uses a Pair class that I have defined, which is also serializable.

Here is my invertedIndex code:

#ifndef INVERTED_IND
#define INVERTED_IND
#include <map> 
#include <string>
#include <vector>
#include "Pair.h"
#include <boost/serialization/access.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>



class invertedIndex
{
    friend class boost::serialization::access;
public:
    std::map<std::string,std::vector<Pair> > m; //term: (docid,freq)


    void updateIndex (std::map<std::string,int>,int); 
    //Updates inverted index given a map(term:freq),int id
    std::map<int,int> queryIndex(std::vector<std::string> terms);
    //queries the inverted index given a list of terms, and returns a map(docID:score)
    invertedIndex chunkIndex(std::vector<std::string> terms);
    //creates an II object with only those terms that are contained in the terms argument
    std::string toString();
    //toString method for debugging
    template<class Archive>
        void serialize(Archive&ar,const unsigned int version)
        {
            ar & m;
        }
private:
    void addTerm(std::string term,std::vector<Pair>);
//add partial result to this inverted index
};

#endif

Here is the Pair header file:

 #ifndef PAIR_T
 #define PAIR_T
  #include <boost/serialization/access.hpp>
  #include <boost/serialization/vector.hpp>
  #include <boost/serialization/string.hpp>
  #include <string>
  #include <iostream>
  #include <sstream>



class Pair
{
friend class boost::serialization::access;
public:
    int docID;
    int freq;
    template<class Archive>
        void serialize(Archive &ar,const unsigned int version)
        {
            ar & docID;
            ar & freq;
        }
    Pair(int x, int y);
    Pair(int x);
    std::string toString();
};

#endif

When I try to write a main method the serializes the above code I get tons of errors from the compiler saying that boost/serialization/access.hpp:109 invertedIndex has no member named serialize.

So my question is am I not allowed to serialize the map data member of the inverted index directly? Is it due to the fact that it's a complex data structure with the Vector<Pair> inside of it?

EDIT: Here's the compilation command and the output

g++ -Wall -g -DBOOST_SYSTEM_NO_DEPRECATED iiTest.cpp Pair.cpp invertedIndex.cpp -o iiTest -lboost_serialization -lboost_system-mt
In file included from Pair.h:4,
                 from invertedIndex.h:6,
                 from iiTest.cpp:1:
/usr/include/boost/serialization/access.hpp: In static member function 'static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = invertedIndex]':
/usr/include/boost/serialization/serialization.hpp:74:   instantiated from 'void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = invertedIndex]'
/usr/include/boost/serialization/serialization.hpp:133:   instantiated from 'void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/oserializer.hpp:139:   instantiated from 'void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/oserializer.hpp:96:   instantiated from 'boost::archive::detail::oserializer<boost::archive::text_oarchive, invertedIndex>'
/usr/include/boost/archive/detail/oserializer.hpp:235:   instantiated from 'static void boost::archive::detail::save_non_pointer_type<Archive>::save_standard::invoke(Archive&, const T&) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
/usr/include/boost/archive/detail/oserializer.hpp:290:   instantiated from 'static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, const T&) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
/usr/include/boost/archive/detail/oserializer.hpp:296:   instantiated from 'static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
/usr/include/boost/archive/detail/oserializer.hpp:507:   instantiated from 'void boost::archive::save(Archive&, T&) [with Archive = boost::archive::text_oarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/common_oarchive.hpp:62:   instantiated from 'void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
/usr/include/boost/archive/basic_text_oarchive.hpp:75:   instantiated from 'void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
/usr/include/boost/archive/detail/interface_oarchive.hpp:64:   instantiated from 'Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = invertedIndex, Archive = boost::archive::text_oarchive]'
iiTest.cpp:34:   instantiated from here
/usr/include/boost/serialization/access.hpp:109: error: 'class invertedIndex' has no member named 'serialize'
/usr/include/boost/serialization/access.hpp: In static member function 'static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = invertedIndex]':
/usr/include/boost/serialization/serialization.hpp:74:   instantiated from 'void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = invertedIndex]'
/usr/include/boost/serialization/serialization.hpp:133:   instantiated from 'void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/iserializer.hpp:173:   instantiated from 'void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/iserializer.hpp:115:   instantiated from 'boost::archive::detail::iserializer<boost::archive::text_iarchive, invertedIndex>'
/usr/include/boost/archive/detail/iserializer.hpp:363:   instantiated from 'static void boost::archive::detail::load_non_pointer_type<Archive>::load_standard::invoke(Archive&, const T&) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
/usr/include/boost/archive/detail/iserializer.hpp:415:   instantiated from 'static void boost::archive::detail::load_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
/usr/include/boost/archive/detail/iserializer.hpp:554:   instantiated from 'void boost::archive::load(Archive&, T&) [with Archive = boost::archive::text_iarchive, T = invertedIndex]'
/usr/include/boost/archive/detail/common_iarchive.hpp:61:   instantiated from 'void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
/usr/include/boost/archive/basic_text_iarchive.hpp:62:   instantiated from 'void boost::archive::basic_text_iarchive<Archive>::load_override(T&, int) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
/usr/include/boost/archive/text_iarchive.hpp:66:   instantiated from 'void boost::archive::text_iarchive_impl<Archive>::load_override(T&, int) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
/usr/include/boost/archive/detail/interface_iarchive.hpp:61:   instantiated from 'Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = invertedIndex, Archive = boost::archive::text_iarchive]'
iiTest.cpp:37:   instantiated from here
/usr/include/boost/serialization/access.hpp:109: error: 'class invertedIndex' has no member named 'serialize'

And the relevant part of the main method (iiTest.cpp):

stringstream ss;
boost::archive::text_oarchive oarch(ss);
oarch << ii; //ii is a previously declared invertedIndex
boost::archive::text_iarchive iarch(ss);
invertedIndex new_map;
iarch >> new_map;
std::cout << new_map.toString() << std::endl;
1
Maybe because your Pair type has no default constructor? - beerboy
Tried adding one, doesn't seem to make a difference, any other thoughts? I'm pretty willing to try anything haha - vkr8
Turns out that adding a default constructor to Pair and invertedIndex fixed the problem, any idea why? - vkr8
If you don't notify people ("@name") nobody will receive the late comments. Only the author of the post you comment to gets auto-notified. - sehe
The constructors are required because of the documented requirements (types must be default constructible, with possible exceptions requiring more code). It should not really lead to the error message you posted, but in the absense of a SSCCE I can't tell why that is. Note that my answer then helped you by adding the missing constructor (while reducing code :)) - sehe

1 Answers

0
votes

I don't see the issue with your code.

Perhaps you can work out what you are doing differently:

Live On Coliru

#include <boost/serialization/access.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <iostream>
#include <sstream>

class Pair {
    friend class boost::serialization::access;

  public:
    int docID;
    int freq;
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        ar &docID;
        ar &freq;
    }
    Pair(int x=0, int y=0) : docID(x), freq(y) {}
    std::string toString();
};

class invertedIndex {
    friend class boost::serialization::access;

  public:
    std::map<std::string, std::vector<Pair> > m; // term: (docid,freq)

    void updateIndex(std::map<std::string, int>, int);             // Updates inverted index given a map(term:freq),int id
    std::map<int, int> queryIndex(std::vector<std::string> terms); // queries the inverted index given a list of terms, and returns a map(docID:score)
    invertedIndex chunkIndex(std::vector<std::string> terms);      // creates an II object with only those terms that are contained in the terms argument
    std::string toString();                                        // toString method for debugging
    template <class Archive> void serialize(Archive &ar, const unsigned int version) { ar &m; }

  private:
    void addTerm(std::string term, std::vector<Pair>);
    // add partial result to this inverted index
};

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
int main() {
    std::stringstream ss;
    {
        boost::archive::text_oarchive oa(ss);

        invertedIndex ii;
        oa << ii;
    }

    std::cout << ss.str() << "\n";

    {
        boost::archive::text_iarchive ia(ss);
        invertedIndex ii;
        ia >> ii;
    }
}

Runs successfully, printing

22 serialization::archive 13 0 0 0 0 0 0