Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

totally stumped, cannot instantiate template class

Status
Not open for further replies.

jms137

Programmer
Oct 6, 2002
18
GB
Hello all.

I am really at my wits end here. I cannot instantiate an instance of a templated class. ( I have looked through the archives and can't find an answer!)

My templated class is called Jstack. It is only part comleted but enough to test:

template< class STACKTYPE> class Jstack
{
public:
Jstack(void);
~Jstack() {void};
void push(STACKTYPE objIn);
STACKTYPE pop ();

private:
STACKTYPE * stackPtr;
int top;
};


template<class STACKTYPE>
Jstack<STACKTYPE>::Jstack(){

stackPtr = new STACKTYPE[10];
top = 0;
}

template<class STACKTYPE>
void Jstack<STACKTYPE>::push(STACKTYPE pushVal){

if(top < 11)
{
stackPtr[top++] = pushVal;
}
else
{
//make a bigger array
}

}

template<class STACKTYPE>
STACKTYPE Jstack<STACKTYPE>::pop()
{
return stackPtr[top--];
}

//*********************************************

Now I test it with this little program:

#include <iostream.h>
#include &quot;Jstack.h&quot;

int main ()
{
Jstack < int > myStack();
myStack.push(3);
return 0;
}

//*************************************

Ok the problem is when I type &quot;myStack.&quot; I expect the little pop up menu to come up which offers the choice of member functions. Unfortunatley, it doesnt and sure enough when I compile I get:

error C2228: left of '.push' must have class/struct/union type

In other words, my instance of Jstack has not been instantiated properly. Can anyone tell me why this is? It's driving me nuts.

thanks,
john
 
I'm not sure if this is the problem but try this:

[tt]
template< class STACKTYPE> class Jstack
{
public:
Jstack();
~Jstack() {};
void push(STACKTYPE objIn);
STACKTYPE pop ();

private:
STACKTYPE * stackPtr;
int top;
};
[/tt]
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
I notice couple of problems here:

1. Your destructor is defined like this:
~Jstack() {void};
change it to
~Jstack() {};

2. Your instantiation of the template looks wrong.
Jstack < int > myStack();

Try changing it to:
Jstack < int > myStack;

Hope this helps.


 
[tt]Jstack < int > myStack();[/tt] shouldn't make any difference - like I pointed out earlier the problem is more likely to do with your incorrect decalrations for constructor and destructor. These should not have void keywords in the declarations.
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
I just tested it and actually we're both right - I've also made the destructor virtual. Here's the code:

[tt]template< class STACKTYPE> class Jstack
{
public:
Jstack();
virtual ~Jstack() {};
void push(STACKTYPE objIn);
STACKTYPE pop ();

private:
STACKTYPE * stackPtr;
int top;
};


template<class STACKTYPE>
Jstack<STACKTYPE>::Jstack(){

stackPtr = new STACKTYPE[10];
top = 0;
}

template<class STACKTYPE>
void Jstack<STACKTYPE>::push(STACKTYPE pushVal){

if(top < 11)
{
stackPtr[top++] = pushVal;
}
else
{
;//make a bigger array
}

}

template<class STACKTYPE>
STACKTYPE Jstack<STACKTYPE>::pop()
{
return stackPtr[top--];
}



int main ()
{
Jstack<int> myStack;
myStack.push(3);
return 0;
}[/tt]
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
Thanks guys

You were all right! The problem was that the instantiation:

Jstack < int > myStack();

is wrong, it should not have the brackets in there.

Also i took out the 'void' from the constructor & destructor prototype, and it works now. One odd thing I noticed is that the menu which pops up when u type the &quot;.&quot; operator does not contain the member functions of the template class, but they still work if u type them in manually.

Although I am new to C++, i am guessing that this is because the compiler does not generate code from any template member functions until they are instantiated, or something....i think u have to use the 'explicit' word somethwere.

anyway, thanks
john
 
Yes, Visual C++ 6.0 has some weird ways of working with template classes and functions. Some compilers wouldn't complain about the parentheses when you create myStack object but it appears VC++ 6 does.
I recall when I first got my copy of VC++ 6 and I tried creating a simple template function to swap two values. I couldn't get it to work for the life in me and I couldn't figure out what the problem was!
In the end, I finally realized that VC++ 6.0 requires parameter names in the prototype (unlike regular functions).
I believe this &quot;bug&quot; has been addressed in VC++ 7.0

:)
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
When you say:
Jstack < int > myStack();

it actually is a prototype declaration of a function called &quot;mystack&quot; which returns a &quot;Jstack<int>&quot; and takes no arguments. It is not a variable declaration at all...




 
yes, true - but the point I was trying to get across is this:

[tt]template< class STACKTYPE> class Jstack
{
public:
Jstack(int);
~Jstack() {};
void push(STACKTYPE objIn);
STACKTYPE pop ();

private:
STACKTYPE * stackPtr;
int top;
};


template<class STACKTYPE>
Jstack<STACKTYPE>::Jstack(int i){

stackPtr = new STACKTYPE[[color]i[/color]];
top = 0;
}

Jstack < int > myStack(20);

[/tt]

Passing a parameter to the constructor works anyway. In this case, we're initializing the array with an initial size of 20 (pointless except to show that this code works).
Some compilers will accept the empty parenthesis just like a 'default'.
tellis.gif

[sup]programmer (prog'ram'er), n A hot-headed, anorak wearing, pimple-faced computer geek.[/sup]​
 
Through my experimentation, it seems that if you declare a default constructor like this:

Jstack(void);

You must omit the parenthesis in an instantiation, but if you declare the constructor like:

Jstack();

You must instantiate with[\i] parenthesis.

Does anyone know if there is any truth to what I'm saying?
 
doh!

You must instantiate with parenthesis.

Does anyone know if there is any truth to what I'm saying?
 
I don't know if there's any truth to it, but it's not Standard C++, and it's not one of those &quot;special features&quot; VC++ uses (at least in my version).

The way the constructor is declared should have no bearing on the meaning of a statement of the form &quot;Type name()&quot;; such a statement always means a function declaration.

Nor can you change this behavior by using a void when you call the constructor. &quot;Type name(void)&quot; is still a function declaration.

Now, some compilers may allow what you describe, and some might allow the use of a void at the call to make the distinction, but neither is Standard C++.
 
Upon further examination, I think you're absolutely right, chipper (for my compiler too).

I swear I did something the other day that made me second guess my knowledge of class initialization, but for the life of me, I can't remember what it was. Knowing me, I'm probably just confusing details with something else.

Oh well.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top