2

A basic template class might look something like this:

Example.h

template<class T> 
class Example {
public:
    T doSomething();
};

Example.cpp

#include "Example.h"

template<class T>
T Example<T>::doSomething() {
    // ...
    return  0;
}

In a class this small, this is fine, but when dealing with larger classes, potentially with more template args, it can become annoying to have to retype template<class T, ...> and Example<T, ...> constantly, and if the template args change, you have to change it everywhere. Putting the aforementioned code in two preprocessor defines seems to work fine, but looks really messy:

Example.cpp

#include "Example.h"

#define Tmpl template<class T>
#define Example Example<T>

Tmpl 
T Example::doSomething() {
    // ...
    return 0;
}

Is there a slightly cleaner way of doing this, or is #define the only way I have?

the4naves
  • 333
  • 2
  • 9
  • 2
    You want to be careful about defining your template methods in a cpp file because if they're not in the header you'll get a link error when you include `Example.h` in other build units. – Patrick Roberts Apr 11 '21 at 21:23
  • 4
    Most likely there should not be an Example.cpp. [https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – drescherjm Apr 11 '21 at 21:26
  • @PatrickRoberts Good point, I forgot about that. That being said, I think you still can get it to work by modifying the code a bit, and I'd rather not define all my functions in the header. If I remember correctly, putting the definition in the header would solve my problem though, so I'll keep it in mind. – the4naves Apr 11 '21 at 21:32
  • @dxiv Sort of, that's what I'm trying to avoid, but if there really is no cleaner way to write it, I'm happy to accept it. – the4naves Apr 11 '21 at 21:39
  • 2
    I would advise against the #define and instead just type it out. The reason is it reduces readability for others reading your code. – drescherjm Apr 11 '21 at 21:39
  • @the4naves yes, if you remove the `#include "Example.h"` from your cpp file and add `#include "Example.cpp"` to the end of your header file, that would be the necessary modification. But that ends up being effectively no different than just defining your methods where they're declared. – Patrick Roberts Apr 11 '21 at 21:40
  • @PatrickRoberts I think you can also explicitly instantiate template instances you need in the source file, but it sounds like the best option is just to write everything out. – the4naves Apr 11 '21 at 21:44
  • 1
    If you don't want to include the code inline within the class itself (which I generally consider the least messy way of doing template code) then using an #include "my_template.inl" is about as good as you can do (the .inl extension simply being a hint that the file should not be treated as a translation unit on its own which using .cpp does) – SoronelHaetir Apr 11 '21 at 21:45
  • @the4naves That's what the C++ syntax requires, like it or not. Also, it may not be such a good idea to (ab)use macros that way. For example `#define Example Example` will bite you back if you try to instantiate the template later `Example var;`. – dxiv Apr 11 '21 at 21:52
  • @dxiv I know I have to write it out somehow, I was just hoping to be able to abstract away writing the same thing over and over again, but I agree macros are not a very good solution, for that exact reason. – the4naves Apr 11 '21 at 21:54
  • @SoronelHaetir I'm using cmake as a build system, could I accomplish the same thing by just leaving the cpp file out of the target files? .inl probably gives a better idea of what the file does, but just wondering. – the4naves Apr 11 '21 at 22:08

1 Answers1

1

By the sounds of it, the best option is just to write out everything in full. Unfortunate, but I suppose this is what find/replace is for. Additionally, the code in my question would give linker errors when used in context, unless function definitions were given in the header, or (I think) if template instances were explicitly written in the source file (Why can templates only be implemented in the header file?).

the4naves
  • 333
  • 2
  • 9