Skip to main content
gamedev.net
🔒 Locked

Template Question

Started by The Bag Feb 19, 2003 at 11:08 AM 15 replies 500+ views
Original Post
The Bag
The Bag
I have 2 template classes, one for a stack, one for a queue - these are subclasses of Container (also a template). An instance of either of these is called through either MakeQueue or MakeStack returning a Container*. EDIT: the code is in the second last post. [edited by - The Bag on February 19, 2003 6:23:27 PM]
The Bag
The Bag
Code deleted - see latest post for most up to date code.

[edited by - The Bag on February 19, 2003 6:24:07 PM]
CpMan
CpMan
You seem to have a variety of errors...I'm surprised that it's even linking.

You templated the function, but if that is your exact declaration...then it's not correct. Here's what it should be:



class Container {
public:
template < typename T >
static Container* MakeStack() {
return (Container*)(new Stack< T >());
}
};

template < typename T >
class Stack : public Container {
public:
T a;
};

Used like:

int _tmain(int argc, _TCHAR* argv[])
{
Container* c;
c = Container::MakeStack< int >();
return 0;
}




I may be misunderstanding what you're trying to do, but that seems to be what I see.


[edited by - CpMan on February 19, 2003 12:17:15 PM]

[edited by - CpMan on February 19, 2003 12:20:11 PM]

[edited by - CpMan on February 19, 2003 12:22:58 PM]

STUPID < >'s

[edited by - CpMan on February 19, 2003 12:24:46 PM]

[edited by - CpMan on February 19, 2003 12:28:13 PM]
VSEDebug Visual Studio.NET Add-In. Enhances debugging in ways never thought possible.
The Bag
The Bag
Thanks that has fixed what I was trying to do.

One problem, when I compile main I get this:

  Compiling...
main.cpp
E:\Documents and Settings\M Hanlon\Desktop\test\main.cpp(11) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1794)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Error executing cl.exe.


[edited by - The Bag on February 19, 2003 12:34:11 PM]
CpMan
CpMan
Visual C++6 by my guess...

1) Make sure you have the latest SP installed. This may fix it.
2) There are certain conditions on which the compile will fail when certain template definitions/declarations are made. libGDN has run into a few of these, and although I don''t think that that code will do it...it''s possible. Do you have anymore template usage elsewhere?



Gamedev for learning.
libGDN for putting it all together.
An opensource, cross platform, cross API game development library.
VSEDebug Visual Studio.NET Add-In. Enhances debugging in ways never thought possible.
CpMan
CpMan
VC6 does this for me..looking for the workaround...
VSEDebug Visual Studio.NET Add-In. Enhances debugging in ways never thought possible.
The Bag
The Bag
Does it work with VC7? I have access to this elsewhere but not at home - where I do most of my work.

SP1 is the latest I have installed - so I''m going to look for an update.
CpMan
CpMan
Does under 7.1, and should under 7.0. Gotta go for now. Anyone else know what the workaround is?



Gamedev for learning.
libGDN for putting it all together.
An opensource, cross platform, cross API game development library.
VSEDebug Visual Studio.NET Add-In. Enhances debugging in ways never thought possible.
The Bag
The Bag
Thanks for your help CPMan.

Okay - I've now installed SP5, but it's still happening.

Workaround? Anyone?

[edited by - The Bag on February 19, 2003 1:28:12 PM]
The Bag
The Bag
okay I just got someone to test it on VC7 - which gives the following error:
test error LNK2019: unresolved external symbol "public: static class  * __cdecl CContainer::MakeStack(void)" (?MakeStack@?$@H@CContainer@@SAPAV1@XZ) referenced in function _main  


the project is split into 3 files,
main.cpp:

  
#include "Container.h"

int main()
{
Container* c;
c = Container::MakeStack<int>();
return 0;
}


Container.h:

  
#define MAX 100

class CContainer
{

public:
CContainer();
virtual ~CContainer();

template<class Type> static CContainer* MakeStack template<class Type> static CContainer* MakeQueue();

virtual void put(int add) = 0;

virtual int get() = 0;

};


and container.cpp:

  
#include "Container.h"

template <class Type>class CStack : public Container{

Type stack[MAX];
int tos;

public:
CStack(){
tos = 0;
}

void put(int add){
if(tos == MAX){
cout << "OVERFLOW" << endl;
}else{
stack[tos] = add;
tos++;
}
}

int get(){
if(tos == 0){
cout << "UNDERFLOW" << endl;
return 0;
}else{
tos--;
return stack[tos];
}
}
};

template <class Type> class CQueue : public Container{

Type queue[MAX];
int toq;

public:
CQueue(){
toq = 0;
}

void put(int add){

if(toq == 100){
cout << "OVERFLOW" << endl;
// OVERFLOW

}else{
queue[toq] = add;
toq++;
}
}

int get(){

if(toq == 0){
cout << "UNDERFLOW" << endl;
// UNDERFLOW

return 0;
}else{
// move everything down one

int temp = queue[0];

toq--;
for(int i = 0;i<toq; i++){
queue[i] = queue[i+1];
}

return temp;
}
}
};


template <class Type> CContainer* CContainer::MakeStack(){
return (CContainer*)(new CStack<Type>());
}

template <class Type> CContainer* CContainer::MakeQueue(){
return (CContainer*)(new CQueue<Type>());
}


Any ideas where I''m going wrong - this is my first attempt at templates so be gentle on me ;-).

thx
sjelkjd
sjelkjd
You should put all class declarations in a header file, as you''ll need to include the file, and it''s against convention to #include a cpp file.

Secondly, templated functions need to be declared and defined in the header, otherwise the linker won''t find them.
The Bag
The Bag
Right I've now changed it too (latest code):

Container.h:

              
#define MAX 100

template <class Type> class CStack;


class CContainer
{

public:

template<class Type> static CContainer* MakeStack();

template<class Type> void put(Type add);

template<class Type> Type get();

};

template <class Type>class CStack : public CContainer{

Type stack[MAX];
int tos;

public:
CStack();
void put(Type add);
Type get();
};



Container.cpp:

  
#include <iostream>

#include "Container.h"

using namespace std;

template <class Type> CStack<Type>::CStack(){
tos = 0;
}

template <class Type> void CStack<Type>::put(Type add){
if(tos == MAX){
cout << "OVERFLOW" << endl;
//stack overflow

}else{
stack[tos] = add;
tos++;
}
}

template <class Type> Type CStack<Type>::get(){
if(tos == 0){
cout << "UNDERFLOW" << endl;
//stack underflow

return 0;
}else{
tos--;
return stack[tos];
}
}

template <class Type> CContainer* CContainer::MakeStack(){
return new CStack<Type>();
}


main:

  
#include "Container.h"

using namespace std;

int main()
{
CContainer* c;

c = CContainer::MakeStack<char>();

return 0;
}


but this line of main:
c = CContainer::MakeStack > int < ();

is still giving the same problem



[edited by - The Bag on February 19, 2003 5:18:43 PM]

[edited by - The Bag on February 19, 2003 5:39:08 PM]
The Bag
The Bag
Right I''ve compiled it using Dev C++ rather than MSVC++ so I can get a real error message out of it.

At the link stage I get the following.

main.cpp: undefined reference to `CContainer * CContainer::MakeStack()''

using the code from the last post.

What do I need to do?
fizban75
fizban75
You need to put *all* template class and function definitions in the header file. There should be *no* instances of the word "template" in your cpp file.
The Bag
The Bag
hmm, if that''s what it''ll take to work.

One of the specs for this was to hide as much of the implementation as possible (ie not in the header).
The Bag
The Bag
okay - everything is now in the header, but it still doesn't work.

It still doesn't link under MSVC++, but it does in Dev C++ until I add c-> put(8); then it cannot link again.

[edited by - The Bag on February 19, 2003 6:41:43 PM]
fizban75
fizban75
If you're using templates, you can't hide the code, sorry.

Just think about it. Templated code has to be visible at compile time, because it's compiled based on the template parameters you give - the types. You can't compile the template code separate from where it's used because it doesn't have any types yet! Therefore, all template definitions must be in the header. Any C++ book on template programming will show you this.

Frankly, I don't think your code is going to work at all the way you have it structured. Is this a class assignment? If it is, I can't help you any further, but if not, post your code as it currently stands and I'll critique it more.

[edited by - fizban75 on February 19, 2003 7:49:23 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.