Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ templates declare in .h, define in .hpp

I saw some code in which the developer defined a class template in a .h file, and defined its methods in a .hpp file. This caught me a bit by surprise.

Are there are particular conventions in C++ when dealing with templates and what files they should be in?

For example say I had a Vector class template with methods for vector operations (add, subtract, dot, etc.). I would also want to specialize certain functions if the template argument is a float (comparison operators). How would you separate all of this between files (specify whether .h, .hpp, .cpp).

like image 794
rhubarb Avatar asked Aug 19 '10 21:08

rhubarb


People also ask

Is .h and .HPP same?

In conventional use (by boost, etc), . hpp is specifically C++ headers. On the other hand, . h is for non-C++-only headers (mainly C).

Why do templates have to be defined in header files?

To have all the information available, current compilers tend to require that a template must be fully defined whenever it is used. That includes all of its member functions and all template functions called from those. Consequently, template writers tend to place template definition in header files.

Can templates be defined in cpp?

The class template in c++ is like function templates. They are known as generic templates. They define a family of classes in C++. Here Type is a placeholder type name, which will be specified when a class instantiated.

Why are template definitions required to be placed in a .h file instead of a .cpp file?

A template is not like a function which can be compiled into byte code. It is just a pattern to generate such a function. If you put a template on its own into a *. cpp file, there is nothing to compile.


2 Answers

Typically (in my experience, YMMV) an hpp file is an #include-ed CPP file. This is done in order to break the code up in to two physical files, a primary include and an implementation-details file that the users of your library don't need to know about. It is done like this:

super_lib.h (the only file your clients need to #include)

template<...> class MyGizmo
{
public:
  void my_fancy_function();
};

#include "super_lib_implementation.hpp"

super_lib_implementation.hpp (your clients do not #include this directly)

template<...> void MyGizmo<...>::my_fancy_function()
{
 // magic happens
}
like image 181
John Dibling Avatar answered Sep 19 '22 19:09

John Dibling


That sounds unusual to me. A template's definition and all specializations must be compiled along with its declaration, with the exception of export templates, a feature which effectively doesn't exist.

C++0x does introduce extern template declarations, which allow you to define explicit specializations in a different source file (translation unit). This exists already as an extension in GCC and probably other platforms.

Splitting into two files could help "hide" the implementation a little, or allow some kind of laziness with doxygen, maybe.

Aha! It's also possibly to improve compile time with precompiled headers. The compiler may cache headers on a per-file basis. A separate "implementation" header could then be modified without touching the "interface" header. But not vice versa, the implementation header would still take the bulk of the compile time, and the gain would be very fragile and dependent on the platform and specific changes made. In the end, PCH improves time over several source files, and optimizing header dependencies is pointless.

like image 23
Potatoswatter Avatar answered Sep 18 '22 19:09

Potatoswatter