0

I've lost so much time on this problem. I have two classes, one for a set of cards

#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <vector>

class Set {
private:
  friend class boost::serialization::access;
  std::string _name;
  std::vector<Card*> _cards;

public:
  template <class Archive>
  void serialize(Archive & ar, const unsigned int version);
  Set();
};

And an other for a card itself :

class Card {

  private:
    friend class boost::serialization::access;  
    std::string _front;
    std::string _back;
    std::vector<CardReview> _reviews;    

  public:
    template <class Archive>
    void serialize( Archive & ar, const unsigned int version);
    Card();

};

Here are my serializers :

template <class Archive>
void Set::serialize ( Archive & ar, const unsigned int version )
{
  ar & _cards; // If I comment this line, everything works !!
  ar & _name;
}

template <class Archive>
void Card::serialize ( Archive & ar, const unsigned int version )
{
    ar & _back;
    ar & _front;
    ar & _id;
    ar & _reviews;
}

Unless I comment the line serializing the vector of cards called _cards, I get the following linker error :

[ 33%] Building CXX object CMakeFiles/supercards.dir/set.o
Linking CXX executable supercards
CMakeFiles/supercards.dir/set.o: In function `void boost::serialization::access::serialize<boost::archive::text_oarchive, Card>(boost::archive::text_oarchive&, Card&, unsigned int)':
set.cpp:(.text._ZN5boost13serialization6access9serializeINS_7archive13text_oarchiveE4CardEEvRT_RT0_j[_ZN5boost13serialization6access9serializeINS_7archive13text_oarchiveE4CardEEvRT_RT0_j]+0x1b): undefined reference to `void Card::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive&, unsigned int)'
CMakeFiles/supercards.dir/set.o: In function `void boost::serialization::access::serialize<boost::archive::text_iarchive, Card>(boost::archive::text_iarchive&, Card&, unsigned int)':
set.cpp:(.text._ZN5boost13serialization6access9serializeINS_7archive13text_iarchiveE4CardEEvRT_RT0_j[_ZN5boost13serialization6access9serializeINS_7archive13text_iarchiveE4CardEEvRT_RT0_j]+0x1b): undefined reference to `void Card::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, unsigned int)'
collect2: error: ld returned 1 exit status
make[2]: *** [supercards] Error 1
make[1]: *** [CMakeFiles/supercards.dir/all] Error 2
make: *** [all] Error 2
*** Failure: Exit code 2 ***

I really don't understand why this is happening. If I comment the above mentioned line, there is no compile-time error and the serialization works fine - but the _cards property is not included of course. So this not a linker error, the library is correctly linked. I've spent 3 hours trying to find out what is missing in my code without success.

Any idea would be appreciated,

Thanks !

tobiak777
  • 3,175
  • 1
  • 32
  • 44
  • 1
    You didn't happen to put the `serialize()` implementation in a cpp file, did you? – T.C. Oct 04 '14 at 13:18
  • 1
    Wild guess: the templates are defined in a source file. They need to be in a header, included in every file that uses them. http://stackoverflow.com/questions/495021 – Mike Seymour Oct 04 '14 at 13:19
  • @T.C. Yes I did, is it bad ? – tobiak777 Oct 04 '14 at 13:19
  • @MikeSeymour Thank you for your answers. I have an header file, and a cpp file for each class. Is it a bad practive when serializing ? Where should I define the Archive template if I do so? – tobiak777 Oct 04 '14 at 13:20
  • 1
    @red2nb: Templates usually need to be defined in a header. Move each definition into the class header file. See the duplicate for a full explanation. – Mike Seymour Oct 04 '14 at 13:21
  • Thank you very much for your help, now everything is compiling without problem. Sorry for the duplicate, it's my first time using templates and I didn't suspect that the problem was related to that. – tobiak777 Oct 04 '14 at 13:28

0 Answers0