I want to write a library that to use, you only need to include one header file. However, if you have multiple source files and include the header in both, you'll get multiple definition errors, because the library is both declared and defined in the header. I have seen header-only libraries, in Boost I think. How did they do that?
Declare your functions inline
, and put them in a namespace so you don't collide:
namespace fancy_schmancy
{
inline void my_fn()
{
// magic happens
}
};
Boost uses header-only libraries a lot because like the STL, it's mostly built using class and function templates, which are almost always header-only.
If you are not writing templates I would avoid including code in your header files - it's more trouble than it's worth. Make this a plain old static library.
There are many truly header-only Boost libraries, but they tend to be very simple (and/or only templates). The bigger libraries accomplish the same effect through some trickery: they have "automatic linking" (you'll see this term used here). They essentially have a bunch of preprocessor directives in the headers that figure out the appropriate lib file for your platform and use a #pragma
to instruct the linker to link it in. So you don't have to explicitly link it, but it is still being linked.
The main reason why Boost is largely header-only is because it's heavily template oriented. Templates generally get a pass from the one definition rule. In fact to effectively use templates, you must have the definition visible in any translation unit that uses the template.
Another way around the one definition rule (ODR) is to use inline
functions. Actually, getting a free-pass from the ODR is what inline
really does - the fact that it might inline the function is really more of an optional side-effect.
A final option (but probably not as good) is to make your functions static. This may lead to code bloat if the linker isn't able to figure out that all those function instances are really the same. But I mention it for completeness. Note that compilers will often inline static
functions even if they aren't marked as inline
.
Header-only libraries are used for class templates and function templates, where a specific class or function is created based on their usage. (Detailed information)
If you have to write here is a simple trick. Of course, it uses templates :-)
// Header file: foo.hh
template< bool dummy = true >
class Foo {
// useful things here
};
An otherwise-nontemplate class is deliberately templatized using a (dummy) template argument of type bool
which defaults to true
. To use this, all user code has to type two extra characters. Instead of usual
Foo foo;
they have to write it as following
// Any source file: bar.cpp
#include "foo.hh"
Foo<> foo;
Following two variations would also work
Foo< true > foo; // Same as Foo<> foo;
Foo< false > foo; // Since the bool argument is just a dummy