0

I have a class:

// A.h
class A
{
    void foo();
    template <class T> void bar( T someVar );
}

#include "A.tcpp"

When I build it, I get linker errors. However, if the whole class would be a template, then the above example would build perfectly fine. So my question is:

How do I stick to the pattern of having ALL definitions in the cpp file, when having template member functions as opposed to having a template class?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Lukas Kalinski
  • 2,213
  • 24
  • 26
  • @drescherjm Because the project follows that pattern, as explained here: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file/495056#495056 – Lukas Kalinski Feb 21 '18 at 18:42
  • Include the cpp as you're doing but don't compile it. I would also suggest using another extension (since it doesn't really mater) .inc or .inl are good. – aram Feb 21 '18 at 18:42
  • @Aram Yeah, actually I call them .tcpp, but didn't want to confuse too much here. What do you mean, don't compile it? – Lukas Kalinski Feb 21 '18 at 18:43
  • @drescherjm I was hoping for a different answer, but if that's how it is then I'll have to do with that. – Lukas Kalinski Feb 21 '18 at 18:44
  • Now with the edits, I assume in this case `.tcpp` files are not being compiled in your project the same way a `.cpp` file would be. Did you implement `foo()` in a `.cpp` file and not your `.tcpp` file? – drescherjm Feb 21 '18 at 18:50
  • @drescherjm No, all the definitions are in the .tcpp file. Now I see what you meant with not compiling it. – Lukas Kalinski Feb 21 '18 at 18:51

2 Answers2

2

If you are going to split a a class that has template functions and non template functions into a header file and a tcpp file then you only put the template definitions in the tcpp file. The non template definitions still needs to go into a regular cpp file.

Putting the non template code in the tcpp file includes it back into the header file and then that means it gets defined in every translation unit it gets included into.

In this case that means you should have

// A.h
class A
{
    void foo();
    template <class T> void bar( T someVar );
}

#include "A.tcpp"

// A.tcpp
template <class T> void A::bar( T someVar ) { some code; }

// A.cpp
#include "A.h"

void A::foo() { some code; }
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
0

I found the solution, it is not as nice as I would like, but it will do in my case. We can insert the following line at the end of the tcpp file:

template void A::bar<int>( int );
// And so on, for all types that should be supported.

It is called function template instantiation.

Lukas Kalinski
  • 2,213
  • 24
  • 26