Template inheritance and linker error

L

little.freaky

Hello group,

I have a problem with template classes and inheritance. I've searched
on the internet to find a solution but all the examples look the same
as my code (as far as I can tell) and I can't find my mistake (maybe
there's something wrong with my eyes).

I've two classes:

template< class T >
class ITestTemplateA
{
public:
ITestTemplateA() { };
virtual ~ITestTemplateA() { };

};

template< class T >
class TestTemplateB : public ITestTemplateA< T >
{
public:
TestTemplateB();
virtual ~TestTemplateB();

};

and the implementation of TestTemplateB:

template < class T>
TestTemplateB<T>::TestTemplateB()
{

}

template< class T >
TestTemplateB<T>::~TestTemplateB()
{

}

Now I want to instantiate an object of type TestTemplateB:

TestTemplateB<ITrack>* track = new TestTemplateB<ITrack>();

Where ITrack is another class, but I think that the source-code to that
class isn't important (?). This compiles but the linker shows an error:


error LNK2001: unresolved external symbol "public: __thiscall
TestTemplateB<class ITrack>::TestTemplateB<class ITrack>(void)"
(??0?$TestTemplateB@VITrack@@@@QAE@XZ)


Can somebody tell my what I'm doing wrong?

thanks in advance
Michael Doswald
 
B

benben

Now I want to instantiate an object of type TestTemplateB:
TestTemplateB<ITrack>* track = new TestTemplateB<ITrack>();

Where ITrack is another class, but I think that the source-code to that
class isn't important (?). This compiles but the linker shows an error:


error LNK2001: unresolved external symbol "public: __thiscall
TestTemplateB<class ITrack>::TestTemplateB<class ITrack>(void)"
(??0?$TestTemplateB@VITrack@@@@QAE@XZ)


Can somebody tell my what I'm doing wrong?


It is important. When the compiler can't see the source code of the
class template, it assumes the instantiation is elsewhere. When it sees
the source code elsewhere it wouldn't know what T is used to instantiate
it, so it won't emit code for it. In fact, the compiler may not even
know what ITrack is when it is compiling the class templates, let alone
knowing that ITrack is used to instantiate the templates. You ended up
with linker complaining about unresolved reference.

To formal solution is to export your class template. But sorry to say,
this feature isn't implemented on most systems so you will have to check
yours (for example, Visual C++ compiler doesn't support that.)

The other solution is to put all the implementation of the class
template in the header file so the compiler sees it when it is asked to
instantiate. I believe C++ linkers, in this case, are able to strip away
redundant code. This also helps effective inlining, too.

thanks in advance
Michael Doswald

Ben
 
L

little.freaky

Now I want to instantiate an object of type TestTemplateB:
To formal solution is to export your class template. But sorry to say,
this feature isn't implemented on most systems so you will have to check
yours (for example, Visual C++ compiler doesn't support that.)

As a matter of fact, I am using Visual C++ :)

The other solution is to put all the implementation of the class
template in the header file so the compiler sees it when it is asked to
instantiate.

I've tried this solution and it works. Thanks for your help!

Michael
 
D

dasjotre

Hello group,

I have a problem with template classes and inheritance. I've searched
on the internet to find a solution but all the examples look the same
as my code (as far as I can tell) and I can't find my mistake (maybe
there's something wrong with my eyes).

I've two classes:

template< class T >
class ITestTemplateA
{
public:
ITestTemplateA() { };
virtual ~ITestTemplateA() { };

};

template< class T >
class TestTemplateB : public ITestTemplateA< T >
{
public:
TestTemplateB();
virtual ~TestTemplateB();

};

and the implementation of TestTemplateB:

where is this implementation, in which file?
template < class T>
TestTemplateB<T>::TestTemplateB()
{

}

template< class T >
TestTemplateB<T>::~TestTemplateB()
{

}

Now I want to instantiate an object of type TestTemplateB:

does compiler know what ITrack is at this point?
TestTemplateB<ITrack>* track = new TestTemplateB<ITrack>();

Where ITrack is another class, but I think that the source-code to that
class isn't important (?).

It is if the TestTemplateB/A use it in the constructor
or have it in the body as a member. you would
get a compiler error thou ...
This compiles but the linker shows an error:
error LNK2001: unresolved external symbol "public: __thiscall
TestTemplateB<class ITrack>::TestTemplateB<class ITrack>(void)"
(??0?$TestTemplateB@VITrack@@@@QAE@XZ)

The linker can't see the implementaiton of
the constructtor, again, where is it?
Did you put it in cpp file?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top