0

For maintainability reasons, I need to split the declaration and the definition of a template class. I want to know what is the correct way to compile the file if I'm using this design choice.

So, as a minimal reproducible example (using templated function just to be more compact) consider:

Header file foo.hpp where I declare a templated function myfun

//file foo.hpp
#ifndef foo_hpp
#define foo_hpp


template <typename T>
void myfun();


#endif /* foo_hpp */

Source file foo.cpp file where I define the function myfun

//file foo.cpp
#include "foo.hpp"
#include <iostream>


template <typename T>
void myfun(){
    std::cout << "Call to myfunc \n";
}

template void myfun<int>();

Finally, the main.cpp file that uses myfun<int>

#include "foo.hpp"

int main(){
    
    myfun<int>();
    return 0;
}

I would compile and generate the executable test from command line just by doing:

g++ -o test foo.cpp main.cpp

because in this way the linker is able to see the instantiation of myfun<int>.

Is this the correct way to compile ?


EDIT:

Another possibility is to use a `.tpp file

//file foo.tpp
#include "foo.hpp"
#include <iostream>


template <typename T>
void myfun(){
    std::cout << "Call to myfunc \n";
}

and put it into the .hpp file

//file foo.hpp
#ifndef foo_hpp
#define foo_hpp


template <typename T>
void myfun();

#include "foo.tpp"    

#endif /* foo_hpp */

Finally, the main.cpp file that uses myfun<int>

#include "foo.hpp"

int main(){
    
    myfun<int>();
    return 0;
}

Now, I compile just by doing:

g++ -o test main.cpp

This works, but as I include the .tpp (which includes the header) into the header, it seems I am including the header into itself, and it's pretty weird

FEGuy
  • 57
  • 8
  • Yes, but it goes against maintability, does it not? – Quimby Jan 22 '21 at 15:59
  • Does this answer your question? [Storing C++ template function definitions in a .CPP file](https://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file) – idmean Jan 22 '21 at 16:00
  • @idmean Actually not that much, as it's not written how they compile and link the examples – FEGuy Jan 22 '21 at 16:01
  • @Quimby Maybe, but I prefer this way also it in terms of readability – FEGuy Jan 22 '21 at 16:02
  • Nothing is stopping you from sticking the implementation at the bottom of the header file. You can still have short `myfun` declaration with comments documenting the API. – Quimby Jan 22 '21 at 16:04
  • @Quimby Right. Just to answer my question: is this the way you'd compile if you had the code organised as I wrote ? – FEGuy Jan 22 '21 at 16:05
  • 1
    Yes, I would :) – Quimby Jan 22 '21 at 16:09
  • That works. That's usually not what people do for various reasons. – SergeyA Jan 22 '21 at 16:09
  • @SergeyA for instance, because you should know a-priori which types your ‘T‘ has to take? – FEGuy Jan 22 '21 at 16:14
  • @VoB yes. And if you, why do you even need a template exposed to the user? Just create as many overloads as you want with fixed types, and forward to the common templated implementation in the cpp file. This seems less esoteric that explicit template instantiation which I have not seen people using often. – SergeyA Jan 22 '21 at 16:16
  • @SergeyA I see, thanks for you comment. I also edited the question with another (found here on SO) approach which is to include a .tpp file in the header. However, it seems weird also this one: it's like the header is included into itself, right? – FEGuy Jan 22 '21 at 16:24
  • @SergeyA I'm sorry, could you please clarify this last point? I'm pretty confused now – FEGuy Jan 22 '21 at 17:32
  • You can break header file into definition and implementation (seems like what `.tpp` is doing here). I have seen that. I am not a fan, but it is not a crazy thing. – SergeyA Jan 22 '21 at 17:35
  • Yes sure, what I wanted to ask was: "in this way, the header it seems like self-included. Shouldn't this be forbidden?" @SergeyA – FEGuy Jan 22 '21 at 17:56
  • Your `tpp` file should not include `hpp` file, since you include that from `hpp` file. @VoB – SergeyA Jan 22 '21 at 20:22
  • @SergeyA You're right: it compiles anyway because it's like if I pasted the whole content of .tpp inside the .hpp. Thanks – FEGuy Jan 22 '21 at 21:55
  • @VoB *in this way, the header it seems like self-included. Shouldn't this be forbidden?* yes, you will receive a recursive-including warning. that's why someone don't like the `.tpp` or `.inl` way to implement the class template. you can just directly implement it at the header, as STL does. – RedFog Jan 23 '21 at 01:57
  • @SergeyA if `.tpp` doesn't include the `.hpp`, it won't be a well-formed code if you don't include the header before, just like a header use something in another header but don't include it. it will break the intellisense. – RedFog Jan 23 '21 at 02:01
  • @RedFog Actually, if it's self-included and I use header-guards, then I'm "safe", but I agree with you that it's not the best. Also, I do not obtain any warning, even compiling with ‘-Wall‘ – FEGuy Jan 23 '21 at 10:12

0 Answers0