Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > C++ newbie problems: template classes

C++ newbie problems: template classes
Thread Tools
Mithras
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 25, 2002, 08:06 AM
 
Hi all.

I'm a beginning CS student, just tackling intro C++. Everything has been fine thus far; however, a new unit on template classes is clobbering me.

I'm using Project Builder. If I make a very simple project that involves template classes, the project compiles, but I get linking errors about undefined symbols.

Example:

main.cpp
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
#include &lt;iostream&gt;
#include <font color = red>"myclass.h"</font>

int main () {
Set&lt;int&gt; aPlaySet;
return <font color = blue>0</font>;
}
</font>[/code]

myclass.h
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
#include &lt;iostream&gt;
#include &lt;vector&gt;

template &lt;class T&gt;
class Set
{
public:
Set();
private:
vector&lt;T&gt; theItems;
};
</font>[/code]

myclass.cpp
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
#include <font color = red>"myclass.h"</font>

template&lt;class T&gt;
Set&lt;T&gt;::Set()
{
<font color = brown>//no-op</font>
}
</font>[/code]

I did some web searching that indicated that gcc doesn't do templates very well, such that I need to add <font face = "courier">template class Set&lt;int&gt;</font> and so on, for each kind of Set class I want. That's certainly lame, but I was willing. That works for awhile, but as I add more member functions, I invariably end up with more errors.

One last thing: The prepackaged source code from the book (Accelerated C++), which has template classes, compiles with makefiles just fine. So it must be possible to get templates working, it's just that I'm stupid.

I don't know anything about creating makefiles, but should I go that route if I want things to work? Surely many others want to make template classes in OS X...
     
Mithras  (op)
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 26, 2002, 09:37 AM
 
Hard to believe no one else is doing this.

Anyway, I eventually found a message on the projectbuilder-users mailing list that indicated that gcc is unhappy unless all of your template function implemenations are in the header file with the class definition, instead of in a separate .cpp file.

So for anyone else out there: Just stick everything in your .h
     
kamprath
Junior Member
Join Date: Apr 2000
Location: San Francisco, CA
Status: Offline
Reply With Quote
Apr 26, 2002, 11:19 AM
 
Originally posted by Mithras:
<STRONG>Hard to believe no one else is doing this.

Anyway, I eventually found a message on the projectbuilder-users mailing list that indicated that gcc is unhappy unless all of your template function implemenations are in the header file with the class definition, instead of in a separate .cpp file.

So for anyone else out there: Just stick everything in your .h</STRONG>

Requiring template method implementation in the local compile unit when used (effectively, it should be in the header) is not a "gcc thing," its a "C++ thing." Any C++ book would have covered this.

Michael
--
Michael F. Kamprath
     
Mithras  (op)
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 26, 2002, 01:21 PM
 
Accelerated C++, p142:
The C++ standard says nothing about how implementations should manage template instantiation, so every implementation handles instantiation in its own particular way...

Most current implementations require that in order to instantiate a template, the definition of the template, not just the declaration, has to be accessible to the implementation. Generally, this requirement implies access to the source files that define the template, as well as the header file. How the implementation locates the source file differs from one implementation to another. Many implementations expect the header file for the template to include the source file, either directly or via a <font face = "courier">#include</font>. The most certain way to know what your implementation expects is to check its documentation.
Definitely an implementation, not a specification, issue. But yes, I should have caught this bit before. Thanks for your illuminating, helpful, and kind post.

[ 04-26-2002: Message edited by: Mithras ]

[ 04-26-2002: Message edited by: Mithras ]
     
kamprath
Junior Member
Join Date: Apr 2000
Location: San Francisco, CA
Status: Offline
Reply With Quote
Apr 26, 2002, 04:52 PM
 
Originally posted by Mithras:
<STRONG>

Definitely an implementation, not a specification, issue. But yes, I should have caught this bit before. Thanks for your illuminating, helpful, and kind post.

[ 04-26-2002: Message edited by: Mithras ]

[ 04-26-2002: Message edited by: Mithras ]</STRONG>
Actually, we are both wrong. The C++ Standard does say something about defining a template's implementation outside of the local compile unit. As you suspected, you are allowed to do so, however, like inlined functions defined outside the local compile unit, the implementations must be exported from the compile unit they are in. However, it is noted by Stroustrup that compile/link time is greatly enhanced by always defining template definitions int he local compile unit (but that runs the risk of namespace collisions).

That means you implementation needed to be:

myclass.cpp

<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
#include <font color = red>"myclass.h"</font>

export template&lt;class T&gt;
Set&lt;T&gt;::Set()
{
<font color = brown>//no-op</font>
}
</font>[/code]

Be wary of any programming book that has "Accelerated" in the title. Spend some money and buy Stroustrup's latest C++ definition (WELL worth the money, if you are thinking about being a proffessional developper, don't buy the cheap books). Good books can help you properly resolve issues like this, even if you have been programming for 15+ years. The information on my above comments can be found in P13.7 of "The C++ Programming Language."

Michael

[ 04-26-2002: Message edited by: kamprath ]
--
Michael F. Kamprath
     
Mithras  (op)
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status: Offline
Reply With Quote
Apr 26, 2002, 07:17 PM
 
Thanks a bunch. You took my cross, sarcastic response and responded sincerely and helpfully to it, darn you!

But yes, thanks for explicating it all. I've settled on <font face = "courier">include</font>ing the source back into the header as a fair compromise, for now. I appreciate the thoughts.

I certainly agree with your comment about "Accelerated" - it's definitely a lousy book, intended for work-a-day programmers. (It hands you the STL and tells you to use that, without much discussion of algorithms or data structures or why STL authors made the choices they did...)

I just graduated from a good school with a degree in another field, and decided to take a couple of CS classes - but the cheapness of the school at which I'm taking them is evident in the syllabus, I'm afraid...
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 07:15 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,