Significance of a .Inl File in C++

Significance of a .inl file in C++

.inl files are never mandatory and have no special significance to the compiler. It's just a way of structuring your code that provides a hint to the humans that might read it.

I use .inl files in two cases:

  • For definitions of inline functions.
  • For definitions of function templates.

In both cases, I put the declarations of the functions in a header file, which is included by other files, then I #include the .inl file at the bottom of the header file.

I like it because it separates the interface from the implementation and makes the header file a little easier to read. If you care about the implementation details, you can open the .inl file and read it. If you don't, you don't have to.

When should I use -inl.h files?

This is often done for long function templates. The regular header my_functions.h only contains the declarations, and the implementation file my_functions-inl.h contain the implementations. The reason is that function templates cannot be put in .cpp files. Note that the X.h file includes the X-inl.h file, not the other way around.

Other libraries have different naming conventions: e.g. some of the Boost libraries use .hpp for template headers and .ipp for template implementation files.

C++ library: .hpp + .inl (separate definitions and declarations) vs .hpp only (in-class body code)

I've found my answer in another question.

Question: When should I consider making a library header-only? - and answer is here^.

And the answer is I will break it into .cpp and .hpp files and make it ready to compiler both as header only and static library or DLL.

@Steve Jessop:

If you think your non-template library could be header-only, consider dividing it into two files anyway, then providing a third file that includes both the .h and the .cpp (with an include guard).

Then anyone who uses your library in a lot of different TUs, and suspects that this might be costing a lot of compile time, can easily make the change to test it.

^ this is an awesome idea. It will take a bit more work but it's SO versatile.

UPDATE

It's important to explicitly instantiate^ the templated classes in the .cpp files.

What's the point of a `.inc` file in C++ & C? What situation would you want to use it?

The extension is just a different one than .h or .hpp. I wasn't there when whoever decided to name the file this way. There is no particular reason other than convention that determine extensions in general.

As Jonathan points out, it may be to distinguish it from "regular header files" that are usable anywhere.

The comment above the inclusion of these files is perhaps a reasonable explanation:

// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
#include "Unix/Signals.inc"
#endif
#ifdef LLVM_ON_WIN32
#include "Windows/Signals.inc"
#endif

These contain platform specific parts, it is not, as such, a "header-file", it is just a portion of code that is dependent on the target architecture, and someone decided that it's better to have two separate files than to have a huge #ifdef in the one source file. [A reasonable decision, in my mind, as the Unix file I looked at is several hundred lines, with further stuff included and some more #if]

Incomplete forward declaration using .inl inline files

As far as I searched and understood glm uses forward declarations. type_vec.hpp which is included in every type_vecX.hpp file has declarations and typedefs for all vectors (float-bool,high-low precision) line 103.

What did the trick was the use of templates. First of all I templated the structs

template<typename T>
struct Vector2
{
public:
...
};

and for the constructor in question the changes were

Declaration:

template<typename S>
Vector2(const Vector3<S> & inVec3);

Definition

template <typename T>
template <typename S>
inline Vector2<T>::Vector2(const Vector3<S> & inVec3) :
X(static_cast<T>(inVec3.X)),
Y(static_cast<T>(inVec3.Y))
{}


Related Topics



Leave a reply



Submit