Sign in to follow this  
Unreal

Templates And Inline Class Funcs Outside Header File

Recommended Posts

Hello there! I am Trying to make a some math libs for a 3d engine.. Matrix, Vector, Quaternion etc.. The class with the funtion definitions is getting big but I cant split my code in other files cause I use Templates for the classes and also a lot of inline funtions (for speed). Is there some way to split the funtion definitions to other cpp files without linker errors? Thanks for your time! :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Unreal
Is there some way to split the funtion definitions to other cpp files without linker errors?

No. It is possible, however, to split your header up into multiple headers. You can have one each for Math, Vectors and Quaternions, for instance, and if there are dependencies, they can #include each other.

Read this excellent article for more information about organizing C and C++ code files.

Share this post


Link to post
Share on other sites

//---------------------------------
// Matrix.h
//---------------------------------
#ifndef MATRIX_H
#define MATRIX_H

template <class T>
class Matrix
{
public:
Matrix();
...
}

#include "Matrix.cpp"

#endif




//---------------------------------
// Matrix.cpp
//---------------------------------
#ifndef MATRIX_CPP
#define MATRIX_CPP

template<class T>
Matrix<T>::Matrix()
{
}

#endif

Share this post


Link to post
Share on other sites
wow. Cool! it works!
For both MSVC++ and GCC
I want to ask.. is this corrent way to do this?
Do i have to watch out for something?
it laso works for inline functions! thats cool!

or it is better to add this on the cpp file:

template class Matrix<int>;
template class Matrix<float>;
template class Matrix<double>;

???

(I saw this from http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12 thanks Ryan_001)

Share this post


Link to post
Share on other sites
Quote:
Original post by scottdewald
*** Source Snippet Removed ***

*** Source Snippet Removed ***


.cpp is the wrong extension for a C++ source file that's going to be included. Since most build systems try to build .cpp files automatically, at best you are increasing compile times for no reason, and at worst you're introducing linker errors.

There are a variety of extensions that are far more appropriate:
.h/.hpp - it's just another header really after all.
.inl - "inline" source
.impl - "implementation"
.tpp - "template" file.


Personally, I use .impl.hpp, as it indicates purpouse and is typically an already registered extension in the IDE/Editor near you.

Quote:
or it is better to add this on the cpp file:

template class Matrix<int>;
template class Matrix<float>;
template class Matrix<double>;


For small classes like a Matrix, I typically don't bother. The explicit instantiation method is mainly useful for reducing compile times by seperating use from instantiation, which is more useful with huge template monstosities using the boost::spirit template parser library, for example, rather than small quickly deal with classes.

These would be added to a .cpp file (that's not #included), if you wanted to use them, it's worth mentioning.

Share this post


Link to post
Share on other sites
Quote:
Original post by Unreal
so... which way you suggest? which is more correct? :P


"For small classes like a Matrix, I typically don't bother [with explicit instantiations]."

I'm having a hard time figuring out how to make this any clearer. I'm saying, it's not worth my time, the cost of manually updating that list [of explicit instantiations] isn't worth it to me in that situation.

I then illustrated a counter-example where I would find it worth my time, and the rationale behind why it would be in that situation, compared to this one - that time managing that list would in that situation would use less of my time than the huge template class being recompiled all the time.

So, which is more "correct"? That depends entirely on you. It depends on how fast your computer is, if your project is already monsterously big or not, how big the template code in question is, and if you step out to grab coffee during your rare recompiles, or hit your build key every 10 seconds and scream as your precious seconds are wasted.

Share this post


Link to post
Share on other sites
What I do ALWAYS is what scottdewald suggested, only do not make it a cpp file! It will work in Visual Studio, but likely not elsewhere. Call it Matrix.inl (inl for "inline", as mentioned by MaulingMonkey).

Also, include guards are not needed for the .inl file, as the Matrix.h include guards guarantee that the .inl will only get included once.


//---------------------------------
// Matrix.h
//---------------------------------
#ifndef MATRIX_H
#define MATRIX_H

template <class T>
class Matrix
{
public:
Matrix();
...
}

#include "Matrix.inl"

#endif







//---------------------------------
// Matrix.inl
//---------------------------------

// (No include guards needed)

template<class T>
Matrix<T>::Matrix()
{
}





Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this