Sign in to follow this  
Guru2012

Initializing static variables in templates

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this