Template usage problem

V

Veeru

i have one structure SPageDetails.
i have a template class CStack.

Now i have a pointer of this stack class in another class
"CAnotherClass" as:
class CAnotherClass
{
CStack<SPageDetails> *m_pStack_PageManager;
};

i am trying to instantiate this m_pStack_PageManager pointer as:
CAnotherClass::CAnotherClass()
{
m_pStack_PageManager = new CStack<SPageDetails>();
}

i am getting the following linker error :

AnotherClass.obj : error LNK2001: unresolved external symbol "public:
__thiscall CStack<class SPageDetails>::CStack<class SPageDetails>(int)"
(??0?$CStack@VSPageDetails@@@@QAE@H@Z)
New.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

Also i am a little confused with using this m_pStack_PageManager
pointer :
Can we use it like this:
m_pStackX_PageManager->push(a_sPD_);
or should we use it as:
m_pStackX_PageManager->push<SPageDetails>(a_sPD_);

Can anyone please help...
 
O

Ondra Holub

Veeru napsal:
i have one structure SPageDetails.
i have a template class CStack.

Now i have a pointer of this stack class in another class
"CAnotherClass" as:
class CAnotherClass
{
CStack<SPageDetails> *m_pStack_PageManager;
};

i am trying to instantiate this m_pStack_PageManager pointer as:
CAnotherClass::CAnotherClass()
{
m_pStack_PageManager = new CStack<SPageDetails>();
}

i am getting the following linker error :

AnotherClass.obj : error LNK2001: unresolved external symbol "public:
__thiscall CStack<class SPageDetails>::CStack<class SPageDetails>(int)"
(??0?$CStack@VSPageDetails@@@@QAE@H@Z)
New.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

When you are defining template class, you must write implementation of
methods in header file.
Also i am a little confused with using this m_pStack_PageManager
pointer :
Can we use it like this:
m_pStackX_PageManager->push(a_sPD_);

Yes, this way.
or should we use it as:
m_pStackX_PageManager->push<SPageDetails>(a_sPD_);

No, exact type of m_pStackX_PageManager is decided already in
declaration and compiler knows, what type it is.
 
V

Veeru

Hey Ondra,
thanks a lot... its working now.
Earlier i had used a .h file for template class declaration and
implementation was done in .cpp file.
But as you said i made all the implementation in the .h file itself and
it worked. But i still didnt understand the reason for the linker
error. why was it not able to link for the template.
can you please brief me on this...

Thanks in advance,
veeru
 
S

Simon G Best

Hello!
Hey Ondra,
thanks a lot... its working now.
Earlier i had used a .h file for template class declaration and
implementation was done in .cpp file.
But as you said i made all the implementation in the .h file itself and
it worked. But i still didnt understand the reason for the linker
error. why was it not able to link for the template.
can you please brief me on this...

The idea is that you /should/ be able to do it the way you tried.
There's a keyword for it, 'export', so that you can 'export' templates
from translation units. However, many C++ compilers don't implement
'export', even though it's part of the C++ standard.

To understand why, consider the following little story.

Once upon a time, Alice wrote part of a program, in C++. She declared
some templates in a header file ("alice.hpp"), and defined those same
templates in the source files for the implementation of her part of that
program ("alice1.cpp", "alice2.cpp", and so on). She compiled that part
of the program (producing "alice.o"), and sent the header file to Bob.
Included in the header file was the following declaration:-

template<typename T> class thingy {

// Blah, blah, blah.

some_type<T *> foo (some_other_type);
some_other_type bar (some_type<T *>);
};

As it's just a header file, the definitions of thingy<>::foo() and
thingy<>::bar() are not included. They're in the stuff that Alice
compiled, as normal.

So, Bob received that header file from Alice, and proceeded to write his
part of the program ("bob.cpp"). He defined some new classes, and used
them as template parameters in specialisations of thingy<>. One of his
new classes was class shiny, and he used it as follows:-

#include "alice.hpp"

class puzzler {
thingy<shiny> t;

// Blah, blah, blah.

public:
void f (some_other_type x) { t.bar(t.foo(x)); }
};

puzzler g (puzzler x, some_other_type y) { x.f(y); return x; }

Now, when Bob's g() gets called, it'll call puzzler::f(), which, in
turn, will call thingy<shiny>::foo() and thingy<shiny>::bar(). So,
thingy<shiny>::foo() and thingy<shiny>::bar() will have to be
instantiated - but how? Bob's class shiny didn't even exist when Alice
compiled her part of the program, so those member functions can't exist
in the part she compiled ("alice.o"). Bob only has Alice's header file,
so doesn't have the definitions of thingy<>::foo() and thingy<>::bar()
available. So, how are thingy<shiny>::foo() and thingy<shiny>::bar()
going to get instantiated?

:)

Simon
 

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,796
Messages
2,569,645
Members
45,367
Latest member
Monarch

Latest Threads

Top