[C++] Templates

Started by
13 comments, last by voguemaster 13 years, 4 months ago
Hey people !

I was wondering, if I construct a class holding a custom item through template< typename T > and split the class up into a header and source file, do I need to put the template before each of the member function definitions in the source file?


// CFoo.htemplate< typename T >class CFoo{public:	CFoo( T item );	void Process();private:	T m_item;};


// CFoo.cpptemplate< typename T > // Like this?CFoo::CFoo( T item ){ ... }template< typename T > // Like this? Even when there is no occurence of T in the function?void CFoo::Process(){ ... }


I was getting "Error: argument list for class template "CFoo" is missing" for each of the member functions and pasting the template before them seemed to solve the error, but I'm unsure if I've missinterpreted the use of templates :S
Advertisement
The definition of your template class should be in your header file, you don't need a .cpp file for that class. Attempting to compile it in the cpp will cause errors.
I find it hard to explain, but the compilation of a template is different to normal compilation - a compiled version of the template is only done when it becomes a concrete type, i.e. CFoo<int> so the whole template definition has to be in the header.

Edit: You might find this useful: Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file (parashift C++ FAQ)

[Edited by - stevenmarky on November 20, 2010 6:25:51 PM]
Hm, okay... So in other words I either can't associate complex functions with classes that hold templated member variables, or I need to put all the defintitions in the header file? Sorry if I'm not getting the point, but I can't help but wonder how STL classes like std::vector work then :/
It's just something you have to get used to. Keep templates and inline function definitions in the header file.
Amateurs practice until they do it right.Professionals practice until they never do it wrong.
Quote:Original post by TheBuzzSaw
It's just something you have to get used to. Keep templates and inline function definitions in the header file.


Okay, I guess that's a bearable restriction. Thanks for the clarification guys !
Quote:Original post by Vanderry
Hm, okay... So in other words I either can't associate complex functions with classes that hold templated member variables, or I need to put all the defintitions in the header file? Sorry if I'm not getting the point, but I can't help but wonder how STL classes like std::vector work then :/

I'm pretty sure the standard containers have their interface and implementation all in the header file. Also, you actually can separate a templated class into header and implementation files, but you need to explicitly instantiate the template for every type you'll be using. I've done this before. An example:

// In templated.hpptemplate <class T>class Templated {   // interface};// In templated.cpp// Implementation here// Template instantiationstemplate class Templated<int>;template class Templated<double>;

I'm far from being an expert, so someone else will have to verify whether or not this works in general, or if it just works for me in GCC. I think it should work in general though, since explicitly instantiating the templates means that the linker will be able to find the the necessary code for any other code that uses those templates.

[Edited by - aryx on November 20, 2010 5:42:05 PM]
Quote:
I'm far from being an expert, so someone else will have to verify whether or not this works in general, or if it just works for me in GCC.

It works in general.

Quote:
Sorry if I'm not getting the point, but I can't help but wonder how STL classes like std::vector work then :/

The source is included with your compiler. It might be worthwhile looking at - with the caveat that standard headers usually have to jump through hoops to ensure they don't step on any user identifiers. They have to use "implementation reserved" global identifiers (beginning with two underscores, or an underscore and an uppercase letter). They also need to ensure that any user #defines don't stomp on them, so they generally use these ugly identifiers even for member and local identifiers.

Still, the answer to this and many other questions can often be solved by looking at the source, regardless of how ugly it is.
Quote:Original post by rip-off
Still, the answer to this and many other questions can often be solved by looking at the source, regardless of how ugly it is.


A very good point. I'm sure that would save me a lot of thread-writing, but it's just so therapeutic to ask you guys :) The solution turned into a custom indexing class to be used widely in my applications. C++ is so neat despite its occasional ugliness !
You can separate the header from the source as long as you #include the source file at the bottom of your header. But you have to give your source file an extension that your compiler won't try to compile into it's own translation unit. Like "Class.inl" or something.
Hi,

To understand this in a better way, you can read the section about "Templates in practice" in C++ Templates: The complete guide. In any case, there are two ways
to write functions as well, inlined to the definition or outside the definition, even on the same header file, like so:

1. inlined:

template<typename T>
class MyClass
{
public:
T* m_pT;

void foo(T* t)
{
// call some operation on T
t->bar();
m_pT = t;
}
}


2. outside the definition you must name the class with its full name:

template<typename T>
class MyClass
{
public:

T* m_pT;

void foo(T* t);
}


// now comes the function, notice its preceded by template arguments and MyClass<T> is used as the name of the class it belongs to!
template<typename T>
void MyClass<T>::foo(T* t)
{
// call some operation on T
t->bar();
m_pT = t;
}



Its not always known but they compiler will freely inline functions if written like in 1, but will less likely do so when written in 2. This can affect your code size considerably since the template's header may be included in many compilation units.

I prefer a standard function call unless I *KNOW* that an inline version will serve me better, otherwise its just a lot of waste.

As for .cpp files - either include them at the end of your header file or don't bother with them. As I said before, check out the book for an explanation, its a good one :)
-----------------------------He moves in space with minimum waste and maximum joyGalactic Conflict demo reel -http://www.youtube.com/watch?v=hh8z5jdpfXY

This topic is closed to new replies.

Advertisement