Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a header-only library?

I'd like to package a library I'm working on as a header-only library to make it easier for clients to use. (It's small and there's really no reason to put it into a separate translation unit) However, I cannot simply put my code in headers because this violates C++'s one definition rule. (Assuming that the library header is included in multiple translation units of a client project)

How does one modify a library to make it header-only?

like image 838
Billy ONeal Avatar asked Feb 08 '10 22:02

Billy ONeal


People also ask

How do I create a header-only library in CMake?

Creating a Header-Only CMake TargetBy specifying INTERFACE as the second parameter to add_library , we are no longer allowed to provide source files since the library is not meant to generate any build output.

What is a header-only library in C++?

In the context of the C or C++ programming languages, a library is called header-only if the full definitions of all macros, functions and classes comprising the library are visible to the compiler in a header file form.

Why are some libraries header-only?

Having a header-only library also means you don't have to worry about different platforms where the library might be used. When you separate the implementation, you usually do so to hide implementation details, and distribute the library as a combination of headers and libraries ( lib , dll 's or . so files).


3 Answers

You can use the inline keyword:

// header.hpp (included into multiple translation units)

void foo_bad() {} // multiple definitions, one in every translation unit :(

inline void foo_good() {} // ok :)

inline allows the linker to simply pick one definition and discard the rest.

(As such, if those definitions don't actually match, you get a good dose of undefined behavior...!)


As an aside, member functions defined within a class-type, are implicitly marked inline:

struct myclass
{
    void i_am_inline_implicitly()
    {
        // because my definition is here
    }

    void but_i_am_not();
    void neither_am_i();
};

inline void myclass::but_i_am_not()
{
    // but that doesn't mean my definition cannot be explicitly inline
}

void myclass::neither_am_i()
{
    // but in this case, no inline for me :(
}
like image 102
GManNickG Avatar answered Oct 13 '22 21:10

GManNickG


Use header guards as Liz suggests and don't forget to put "inline" before your function methods.

ie

#ifndef MY_HEADER_H_
#define MY_HEADER_H_

inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
    // Function body
    return retType;
}

#endif
like image 11
Goz Avatar answered Oct 13 '22 21:10

Goz


Also, I think you'll need to avoid any use of global variables or static variables in your header-only-library code.

like image 5
Jeremy Friesner Avatar answered Oct 13 '22 23:10

Jeremy Friesner