When should I consider making a library header-only?
Obviously template libraries need to be header only, but 开发者_开发技巧for non-templates, when should you make things header-only?
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.
Once you know users have the option which way to use the library, the answer probably becomes "offer that option whenever you possibly can". So pretty much any time that including it from multiple TUs wouldn't violate the ODR. For instance, if your non-static
free functions refer to static
globals, then you're out of luck, since the different definitions of that function in different TUs would refer to different objects by the same name, which is an ODR-violation.
You could follow Boost.Asio lead.
They simply provide the two versions of the libraries: header-only and header + library.
They do it with a single macro to be defined (or not) before including their headers. I think the default (if not defined) is to use the header-only version.
See Optional Separate Compilation.
Note how they neatly provide a single source file to be compiled that define everything or the option to link against a dynamically loaded library.
Template libraries need not to be header-only: implementations might well contain some pieces independent of template parameters, and for some reasons (e.g. less code size) separated into a special binary.
I cannot imagine a case where a non-template library really must be header-only. However sometimes it might be reasonable performance-wise to allow inlining of all the code. An example can be a library of wrappers around platform-specific interfaces, e.g. for things like synchronization primitives, thread-local storage, platform- and compiler-specific implementation of atomic operations etc.
Without templates, you'd have actual definitions in the headers. That means that if two files include your header, you'd get multiple definitions and the code will not compile.
In other words, putting definitions in headers is a very bad idea. You should stick to declarations only, and templates.
As for templates, compilers know that you may include the same header more than once, they will not generate the same code over and over again.
EDIT: If you mean "keep everything inlined", I think this is a very bad approach. The header files become completely unreadable, and any change in implementation forces any user of your library to recompile everything.
精彩评论