views:

103

answers:

2

On my C++ project, I recently stumbled upon a little problem: Templates.

I declared a class, Data in my header file (which is shared by each .cpp), and gave it a template function. I implemented it in data.cpp. I soon remembered how templates are compiled on the spot, when they are referred to, and this breaks the declaration/implementation separation done with .h and .cpp files.

So I thought of a little work around, by putting:

class Data {
  template<typename T> void myFunc(T in);
};

#define __DATA_TEMPLATE_IMPL
#include "Data.cpp"
#undef __DATA_TEMPLATE_IMPL

In header.h and:

#ifndef __DATA_TEMPLATE_IMPL

// non-template functions and other stuff....

#else

template<typename T>
void Data::myFunc(T in) {
  // implementation of template function
}

#endif

It is a big workaround, and to the compiler, it looks as if the code between #else and #endif where moved to the header file.

Two questions:

Do you see anything wrong with this? Can you think of any reason this might be wrong, inneficient, or whatever?

Is there any better way (besides actually putting the implementation in the header file)?

+1  A: 

There is nothing technically wrong with this, the compiler won't care. It is however very common to stick the template code inside the header files, that is, there is no compelling reason why it should be in a CPP file.

About your comment that "all functions" are template functions. Here is where the inefficiency may start to show, the one that you suspected. Most compilers I know compile templates slower than normal code. Additionally, since everything is in the header every source unit has more code to parse, further slowing it down. I'm not saying not to use templates, but be aware that they bare a compile time cost.

edA-qa mort-ora-y
Which is why splitting up the templates into multiple header files is important, so the compiler won't have to parse all the template functions available in a library in each translation unit.
In silico
A better solution to accelerating template code is to use precompiled headers. All major compilers have this feature and it will significantly speed compilation up.
TokenMacGuy
+2  A: 

Do you see anything wrong with this? Can you think of any reason this might be wrong, inneficient, or whatever?

Yes.

  • your build tools will either be:

    • so dumb/manual that they don't realise client code needs to be recompiled when the implementation file changes, or
    • smart enough that they do, so...
      • changes to the part of the implementation file that the client code would normally be decoupled from - out of line functions, private implementation etc. - now trigger a recompilation of client code. That decoupling is a primary reason for having headers versus implementation files in the first place. Compromising it is unacceptable for lower-level code in an enterprise scale build.
  • it's just one more thing for other developers to have to discover before they can understand your code.

Is there any better way (besides actually putting the implementation in the header file)?

Better in what way? Is there a practical problem you're trying to solve? If so, there are probably many ways to solve it. If you're problem is simply a frustration with the inelegance, then move on... life's too short.

Tony