Initializing static variables in templates

Started by
3 comments, last by Deyja 17 years, 11 months ago
I am using VC++ 2005. I have a class template located in the file "SchemaParser.h" which defines a static member:
template <typename _alloc>
class SchemaParser
{
protected:
    static SaxBaseNoTemp* rootNode;
};
Then I define the static variable in "SchemaParser.cpp":
#include "SchemaParser.h"

template<typename _alloc> smiXML::SaxBaseNoTemp* smiXML::SchemaParser<_alloc>::rootNode = 0;
But when I include and use SchemaParser in main.cpp, I get the following message: error LNK2001: unresolved external symbol "protected: static class smiXML::SaxBaseNoTemp * smiXML::SchemaParser<class DAll>::rootNode" I suspect it has something to do with the compiler having to make copies of the template, but I haven't found anything on Google to confirm this. I've only found the suggestion that I define a static in the header's corresponding source file. If I move the definition of rootNode to the bottom of SchemaParser.h, it works fine. Does anyone know why this is happening? And why is it giving me a linker error when I define rootNode in SchemaParser.cpp? EDIT: To clarify, I am placing the same line
template<typename _alloc> smiXML::SaxBaseNoTemp* smiXML::SchemaParser<_alloc>::rootNode = 0;
in two different places, and only one (in SchemaParser.cpp) gives me a linker error. What has me perplexed is that only one of them works. [Edited by - Guru2012 on May 20, 2006 3:03:09 AM]
Advertisement
Sorry, this may not be what you want to hear (or it could be just plain wrong hehe) but i did something NEARLY identical to that, unfortunately though, I had to specify the template arguements when i initialized the static variable. so you would have to have

template<StandardAlloc> smiXML::SaxBaseNoTemp* smiXML::SchemaParser<StandardAlloc>::rootNode = 0;

and I'm actually pretty sure that my way is the only way to do it because if you think about it, templates MUST be in header files, wheras template instances (bad term, i'm tired, i mean when you USE a template) can be in source files.

hope that helps
-Dan
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
Yes, if it really comes down to doing it your way, I definitely will as it seems to be of minimal hassle. I'm just hoping there's a more "generic" way to do it.
Template classes are a bit different than normal classes. In the case of static variables u either need to intialize them in the class definition itself, or outside the class but still in the header file (not in a separate C file).

For example:

template <typename T> class Bob {

static const int i = 0;

};


or you could do:

template <typename T> class Bob {

static int i;

};

template<typename T> int Bob<T>::i = 0;


But in either case it must be in the header file. Why? Well a template class isn't actaully a class its mearly a template that the compiler uses to build a class. So it needs the whole template to build the class properly. It seems in your case the lack of a proper static variable definition caused the linker error. Also it seems u have given it an explicit specialization, whereas the code above is a generic specialization (ehh, I hope I didn't butcher the terminology).
It's nice if yuur compiler lets you get away with that, but it's not standard. If you happened to instantiate the template with the same type in two different compilation units, you'd get multiple-definition errors from the linker.

This topic is closed to new replies.

Advertisement