• Advertisement
Sign in to follow this  

Templates - Constructors - Unresolved External Symbol

This topic is 4796 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having some trouble working with templated classes and their constructors, the source below gives an indication of what I'm trying to do, basically I have a templated class that provides a generic implementation and a partially specialised implementation. I want the user of the class to specify the template parameters and the classes to work fine.

namespace myNamespace
{

template <typename T, int amount>
class myGenericClass
{
private:
...
public:
myGenericClass();
~myGenericClass();
};

template <typename T, 4>
class myGenericClass
{
private:
...
public:
myGenericClass();
~myGenericClass();
};

} // end namespace




And then in the .cpp file :

#include "myheader.h"

template <typename T, int n>
myNamespace::myGenericClass<T, n>::myGenericClass()
{
// some kind of initialisation here
}

template <typename T, int n>
myNamespace::myGenericClass<T, n>::~myGenericClass()
{
// shutdown code here
}

template <typename T, 4>
myNamespace::myGenericClass<T, 4>::myGenericClass()
{
// specialised initialisation here
}

template <typename T, 4>
myNamespace::myGenericClass<T, 4>::~myGenericClass()
{
// specialised shutdown code here
}




But when I use the class in a different source file e.g. main.cpp I get an unresolved external symbol error for the constructor and deconstructor of the generic class, even though I have implemented them. The only way that I can get this to work is by either moving the constructor into the source file where the instanciation is defined, e.g. main.cpp, or by moving the constructor in to the original header file e.g. myheader.h and provinding a typedef for commonly used instances for example myGenericClass<int, 10>. I want to be able to pass the template parameters without having to add a typedef to the header where the class is defined and without having to copy the constructor / deconstructor into the new file. Does anyone have any idea how this can be achieved? [Edited by - moagstar on January 6, 2005 8:24:47 AM]

Share this post


Link to post
Share on other sites
Advertisement
Your code wouldn't compile under any of the three compilers I tested it on. First, you cannot separate definition and declaration of templates unless your compiler supports the export keyword (I know of only one compiler that does). Otherwise the definition for the template must be visible in every translation unit that uses the template. Usually this is accomplished by moving the definitions into the header file or #includeing the file containing the template definitions at the end of the template header.

As for the rest of your code, int 4 is not a template parameter. Instead of template <typename T, int 4> you should template only on T and provide the integer 4 as a specialised parameter, i.e.:
template <typename T>
class myGenericClass<T, 4>
{
// ...
};
// ...
template <typename T>
myNamespace::myGenericClass<T, 4>::myGenericClass()
{
}


Enigma

Share this post


Link to post
Share on other sites
Yeah sorry that int shouldn't be there, have edited code to reflect this. I tried taking the implementation of the constructor and deconstructor and putting it in the header file so that myheader.h looks like this :



namespace myNamespace
{

template <typename T, int amount>
class myGenericClass
{
private:
...
public:
myGenericClass()
{
// some kind of initialisation here
}
~myGenericClass()
{
// shutdown code here
}

};

template <typename T, 4>
class myGenericClass
{
private:
...
public:
myGenericClass()
{
// specialised initialisation here
}
~myGenericClass()
{
// specialised shutdown code here
}
};

} // end namespace





But I stil get the unresolved external, the only way I can get it to work is if i pre-define the template parameters of the class using a typedef in myheader.h ala :



typedef myClassFloat4 myNamespace::myGenericClass<float, 4>;





But this is undesirable, I don't want to pre-define the template paramters for all the possible classes that can be used.

Thanks for your input

Share this post


Link to post
Share on other sites
What compiler are you using? Still none of my compilers accept your code because template <typename T, 4> is not valid. 4 is not a valid template parameter, only a valid template argument. The following works for me on all three compilers I tested it on:
//template.h
namespace myNamespace
{

template <typename T, int amount>
class myGenericClass
{
private:
//...
public:
myGenericClass()
{
// some kind of initialisation here
}
~myGenericClass()
{
// shutdown code here
}

};

template <class T>
class myGenericClass<T, 4>
{
private:
//...
public:
myGenericClass()
{
// specialised initialisation here
}
~myGenericClass()
{
// specialised shutdown code here
}
};

} // end namespace

and
// main.cpp
#include "template.h"

int main()
{
myNamespace::myGenericClass<int, 10> i;
}


Enigma

Share this post


Link to post
Share on other sites
Yes your right again, I'm sorry I'm posting from work, my code doesn't look exactly like this I'm trying to do it from memory...I think I will wait until I get home so I can compare my code with your's, thanks for your help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement