0

I'm sitting on this for quite some time now. I just can't find an answer so it would be cool if you guys could help.

There are two classes involved, one (XMLParser) is reading from a ifstream and is deserializing objects and stores them in a local veriable. A second is holding a vector<Someclass *> objVec;, so a vector which holds pointer to objects of a specific type. I'm pulling it all together like this:

ifstream file(filename, ifstream::in);
if (file.is_open())
{
    XMLParser xmlParser;
    file >> xmlParser;
    xmlParser.fill(&objVec);
    file.close();
}

XMLParser.h:

class XMLParser
{
private:
vector<Someclass> someVec;
vector<SomeOtherclass> someOtherVec;
public:
    template<class T> void fill(std::vector<T*> *vec);
    friend std::istream &operator>>(std::istream &stream, XMLParser &ob);
};
std::istream& operator>>(std::istream &stream, XMLParser &ob);

XMLParser.cpp:

std::istream& operator>>(std::istream &stream, XMLParser &ob)
{
    //deserialize objects from stream and store them locally
    return stream;
}

template <class T> void XMLParser::fill(std::vector<T*> *vec)
{
    //fill the vector with the right objects
}

Everything is compiling well, no errors or warnings. But when its time for linking I'm getting a undefined reference to 'void XMLParser::fill<Someclass>(std::vector<SomeClass*, std::allocator<Someclass*> >*)', XMLParser.o is of course provided.

what I've tried, among other things: including the allocator: template<class T> void fill(std::vector<T*, std::allocator<T*> > *vec) -> same error writing a specialization for fill width Someclass: template <> void XMLParser::fill(std::vector<Someclass*> *vec) -> working! but not what I want

I've searched for some examples on the web and none of them is providing the allocator class for the template, so this doesn"t seams to be the way. The specialization is working, but does anyone know why I need to provide a specialization for every class that might come along? Is there a way around? Cause it doesn't seams to be very generic if I have to provide a specialization for every class that might be in the XML.

Thanks Martin

Martin
  • 65
  • 8

2 Answers2

0

You need to define the template in the header file not in the .cpp file. The standard requires that the template definition is present in every translation unit it is declared in (if used).

Simple
  • 13,992
  • 2
  • 47
  • 47
0

There are 2 ways to resolve this. The first, and by far, the most common, is to put the template deceleration in the h file (not only the definition). this can be done either by writing it in the h, or (less common), including the .cpp file in the h.

the other option is to explicitly instantiate the template, in the cpp file, for each and every type you are ooing to use it.

the standard state another option: using "export" before the template deceleration, while keeping the definition in the cpp file. However, I don't know any compiler that actually support this (it was probably also removed in the current standard). the problem with this, is that if using it, there is dependencies between cpp compilation (I can change the template definition, without changing the h file, and all the cpp files that use this template will have to be recompiled (even though the h was not changed..)

yosim
  • 503
  • 2
  • 8