1

I have a header file with a class template. Since I would like to define its member functions in a different file, I created a .tpp file for that purpose. Example below:

a.hpp

#ifndef A_HPP
#define A_HPP

template <typename T>
class A {
  void foo();
};

#include "a.tpp"

#endif // A_HPP

a.tpp

#ifndef A_TPP
#define A_TPP

// #include "a.hpp" ???

template <typename T>
void A<T>::foo(){ /* function body */ }

#endif // A_TPP

According to this question, it is a good practice to include the header files that are used in the file even if they have been included in previous files. Following that logic, should I include the a.hpp file in a.tpp, even if it leads to recursive inclusion (although it doesn't, due to the include guards)?

  • 1
    Including a.hpp in A.tpp can help the IDE find definitions when you're looking at a.tpp even though in practice it won't have any effect when compiling because of the include guards. – Nathan Pierson Nov 30 '21 at 19:45
  • 2
    I'd not include the `a.hpp` from within the `a.tpp` file. Since the `a.tpp` file is a subordinate header file, I'd add a check for the `A_HPP` guard to exist, and I would not have the `a.tpp` file have its own guard. (But it's not clear cut; different folks will do different approaches. I've moved away from having a template implementation file, and these days just put it all in the `a.hpp` itself, at the end.) – Eljay Nov 30 '21 at 19:56
  • Thanks for the inputs. I should have probably mentioned it, this question came to my mind exactly because the IDE didn't find several definitions. – Francisco Castanheira Nov 30 '21 at 20:10
  • When you have file A include file B and file B includes file A, you have a circular dependency and a [single pass compiler](https://en.wikipedia.org/wiki/One-pass_compiler) like the ones typically used to implement C++ is incapable of untangling whether the [chicken or the egg](https://en.wikipedia.org/wiki/Chicken_or_the_egg) comes first. – user4581301 Nov 30 '21 at 20:13
  • Here's [a good Q&A](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) describing how the compiler sees a circular dependency. – user4581301 Nov 30 '21 at 20:14
  • But all that said, I'm with @Eljay . It's rare that there's a good reason to separate split up the template. – user4581301 Nov 30 '21 at 20:15
  • Since `a.tpp` is just an extension of `a.hpp`'s code, only `a.hpp` should ever be `#include`'ing `a.tpp` directly, so there is no need to have header guards inside of `a.tpp` itself since it is already covered by `a.hpp`'s guards, and `a.tpp` should certainly not be `#include`'ing `a.hpp` – Remy Lebeau Nov 30 '21 at 22:23

0 Answers0